我有一个包含~30M元组的表。该表看起来像:
id | first_name | last_name | email
-----------------------------------------
1 | foo | bar | foo@bar.com
还有first_name的索引(btree索引)和last_name的其他索引。
以下查询大约需要200毫秒才能返回结果:
SELECT
*
FROM my_table
WHERE (first_name ILIKE 'a%')
LIMIT 10 OFFSET 0
但是下一个花了大约15秒(添加订单)
SELECT
*
FROM my_table
WHERE (first_name ILIKE 'a%')
ORDER BY last_name asc, first_name asc
LIMIT 10 OFFSET 0
我可以做些什么来改善上一次查询的效果?
答案 0 :(得分: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)
。此索引可用于WHERE
和ORDER BY
,这对于此查询应该是最佳的。
答案 1 :(得分:1)
我假设以下索引会加快ORDER BY
:
create index my_table_lname_fname on my_table (last_name, first_name)
答案 2 :(得分:0)
CREATE INDEX my_table_idx1 ON my_table (last_name ASC NULLS LAST, first_name ASC NULLS LAST);
一些注释没有特别的顺序: