前言
最近因為排序分頁等問題要分析性能,因此就來記錄一下SQL性能分析。
在此使用的是SQL Server的SSMS的執行計畫去分析效能。
實作
1.先開啟執行計畫,就上面兩個黃色標起來的地方
2.再來執行SQL語法。
1 | SELECT |
3.結果底下會出現一個區塊Execution Plan
4.查看每一個語句
5
(撰寫中…未完待續…)
最近因為排序分頁等問題要分析性能,因此就來記錄一下SQL性能分析。
在此使用的是SQL Server的SSMS的執行計畫去分析效能。
1.先開啟執行計畫,就上面兩個黃色標起來的地方
2.再來執行SQL語法。
1 | SELECT |
3.結果底下會出現一個區塊Execution Plan
4.查看每一個語句
5
(撰寫中…未完待續…)
因為發現用PGADMIN建立Table速度太慢(超久的Loading),因此最後就習慣用指令去建立Table了。
以下為在PostgreSQL建立一個遞增+1的SEQ欄位,且為Table的PK。
1 | CREATE TABLE ( |
在這主要介紹PostgreSQL IN、NOT IN的用法
IN:數值在這集合裡面。
NOT IN:數值在不再這集合裡面。
如果有一表如下:
1 | price_record |
IN:數值在這集合裡面。
1 | SELECT * FROM PRICE_RECORD PR |
結果:
1 | id | price |
NOT IN:數值在不再這集合裡面。
1 | SELECT * FROM PRICE_RECORD PR |
結果:
1 | id | price |
最近遇到在PostgreSQL取得近幾天資料的問題,於是在思考是否有比較直覺得寫法?
後來發現用Between或>=都可以。
以下有一個table:
tb_record
1 | seq | record_date(character varying(8)) |
比如今天是,20220310則:
取得昨天到今天的資料
between寫法:
1 | SELECT |
大於等於寫法:
1 | SELECT |
結果:
1 | 5 | 20220310 |
取得近五天資料
between寫法:
1 | SELECT |
大於等於寫法:
1 | SELECT |
結果:
1 | 3 | 20220305 |
其實就是使用NOW()函數與INTERVAL條件去組日期區間去篩選(O)。
並且搭配一些內部的轉型。
以上面結果就是都轉成YYYYMMDD的字串去比較。
最近碰到一個PostgreSQL搜尋與句的問題。
就是怎樣在PostgreSQL達到類似SQL Server的Outer Apply的寫法。
因為需要在原本一對一的表,再去LEFT JOIN一個一對多資料。
並且把一對多資料取得一個結果存進一對一的表,像是Boolean、數量。
目標:
一張是訂單主表,一張是訂單明細表
想以主表為主,取得有幾張明細表數量。
Table如下:
Table ORDER
1 | SEQ |
Table ORDER_DETAIL
1 | SEQ | ORDER_SEQ | NAME |
使用 Lateral :
1 | SELECT |
結果
1 | ORDER_SEQ | ORDER_DETAIL_COUNT |
不用 Lateral:
1 | SELECT |
結果
1 | ORDER_SEQ | ORDER_DETAIL_COUNT |
用LATERAL會比較直覺,就不用最後再去GROUP BY。
如果想繼承上面LEFT JOIN表的條件,那LATERAL優勢就會出來,會顯得簡單很多。
在寫Javascript時會看到??的語法或?.的用法。
在這稍微做解釋:
?.可選鏈:
作用:可以簡化寫法,因為Javascript如果強制叫出不存在的物件會出現錯誤,所以原本寫法都要寫很長去檢查物件屬性是否存在。
1 | const user = {data:{address:"my address"}} |
可以減少巢狀物件取的屬性的程式碼。
??:
作用:左方為null或undefined則會直接回傳右方的值。
1 | const detail = {data:{address:"my address"}} |
上面因為找不到amount所以接回傳10,有的話則回傳amount
感覺未來的Javascript會充斥著 「??」、「?.」
到時候又配上Javascript函式寫法感覺閱讀性會複雜了。(雖然簡化語法,但學習門檻變高)
看自己手上的專案斟酌吧。
在這篇中介紹如何撰寫一個PostgreSQL的stored procedure。
以下是一個固定的模板,我們將以此模板來撰寫。
1 | create [or replace] procedure procedure_name(parameter_list) |
補充:
stored prodcedure沒有回傳值,所以並不會有return expression;的寫法,但你可以加return;讓程式執行到一半停止執行。
POSTGRESQL文件:
A procedure does not have a return value. A procedure can therefore end without a RETURN statement. If a RETURN statement is desired to exit the code early, then NULL must be returned. Returning any other value will result in an error
實際撰寫
目標:
撰寫一個傳送用戶ID回傳用戶資料的procedure。
users資料表:
因為PostgreSQL的stored procedure沒有回傳值,所以就要用參考的方式去拿值。
以下用INOUT refcursor refcursor去當作參考。
IN user_id integer則是要取得資料的使用者id。
1 | CREATE OR REPLACE PROCEDURE get_user_data |
建好後可在左方PGADMIN看到
之後可以用call來執行。
建立一個區域,宣告一個RECORD物件用來印資料、一個refcursor物件用來參考
接著跑loop迴圈,將每個out_ref放進rcd,再用raise notice印出。
如果沒資料則用IF判斷式離開。
1 | DO $$ |
結果:
PostgreSQL的prodcedure並不好寫,因為他沒辦法直接有返回值。要用參考的方式。他不像SQL Server一樣簡單,能直接Select完畢,因為並不具備回傳值。要回傳值就得寫他的function,就不是prodcedure了。
然後,如果想參考SQL Server的prodcedure我之前也有寫一篇:SQL-Server-Stored-Procedure實作範例可以參考。
最近剛好有要在SQL Server中Left Join N筆結果排序後只取得第一筆的需求。
發現Left Join資料結果會有問題,所以發現了Outer Apply作法能夠達到,因此筆記一下。
需求:
撈出每位使用者還沒完成的最早一筆任務。
並以Priority做排序,如果遇到相同層級則以最早新建的資料為主。
Todos資料表:
Users資料表:
sql:
1 | SELECT |
執行結果:
SQL Server有些特殊語法,有時真的得在實作時才會真的碰到。(坑)