0

時,在一張大桌子上進行緩慢查詢我有一個大約30M元組的表格。該表看起來像:當使用order by

id | first_name | last_name | email 
----------------------------------------- 
1 | foo  | bar  | [email protected] 

還有一個索引(btree索引)first_name和其他last_name。

查詢下面tooks 200ms左右返回結果:

SELECT 
    * 
FROM my_table 
WHERE (first_name ILIKE 'a%') 
LIMIT 10 OFFSET 0 

但接下來的一個tooks約15秒(加上由順序)

SELECT 
    * 
FROM my_table 
WHERE (first_name ILIKE 'a%') 
ORDER BY last_name asc, first_name asc 
LIMIT 10 OFFSET 0 

我能做些什麼來改善最後一個查詢的性能?

+2

索引姓氏,名字。 – jarlh

+0

@jarlh我會試試看,謝謝 – Victor

+0

@jarlh寫一個答案讓我接受 –

回答

2

你有索引的兩個選擇此查詢:

SELECT t.* 
FROM my_table 
WHERE first_name ILIKE 'a%' 
ORDER BY last_name asc, first_name asc 
LIMIT 10 OFFSET 0 ; 

一個是爲WHERE條款。最好的指數是my_table(first_name)。第二種可能性是使用ORDER BY,my_table(last_name, first_name)的索引。

哪個更好取決於您擁有的數據。如果整體表現是一個目標,那麼你可能想要試着看看哪個更好。

最後,計算出的指數可能是最好的方法。對於你的情況,編寫查詢爲:

SELECT t.* 
FROM my_table 
WHERE lower(substr(first_name, 1, 1)) = 'a' 
ORDER BY last_name asc, first_name asc 
LIMIT 10 OFFSET 0 ; 

然後,你要索引mytable(lower(substr(first_name, 1, 1)), last_name, first_name)。該索引可用於WHEREORDER BY,這對於此查詢應該是最佳的。

1

我認爲以下指數將加快ORDER BY

create index my_table_lname_fname on my_table (last_name, first_name) 
0

CREATE INDEX my_table_idx1 ON my_table (last_name ASC NULLS LAST, first_name ASC NULLS LAST);

沒有特定的順序一些注意事項:

  • 的ASC NULLS LAST是默認的,但我認爲我會說明如果你想玩命令。
    • 這是多列索引可以幫助您的罕見時間之一。 通常建議您創建大量單列索引,並允許查詢優化器選擇要使用的索引而不是強制它做出決定。
    • 我注意到有一個ILIKE不是高性能的,可能是你真正的問題除非你正在使用pg_trgm包和GIST索引。