为复杂查询选择索引

时间:2013-11-27 04:21:48

标签: sql postgresql indexing

我是数据库世界的新手,所以希望根据以下查询获得有关创建Postgres索引的帮助。我有一堆看起来与此类似的查询,所以我把它变成了通用的,我希望能够学到我在这里学到的知识并应用于其他查询。

此查询汇总一列值并返回按特定类别分组的前100个值。

SELECT sum(col1) as sum_col, t.col10
FROM table1 as s, table2 as up, table3 as g, table4 as t 
WHERE (s.col1 >= 0) AND (s.col2 = 'f')
AND (g.col3 = 1)
AND (up.col4 = s.col5)
AND (g.id = s.col6 )
AND ((g.col7 = up.col8) OR (g.col9 = up.col8))
AND ((g.col7 = t.id) OR (g.col9 = t.id))
AND (t.id = up.col8) 
GROUP BY t.col10
ORDER BY sum_col DESC LIMIT 100

查看WHERE子句,这是我已经确定为表的索引。我不确定这是否正确,或者我是否需要添加更多的多列。 id是主键,因此我将它们排除在下面的索引之外。

Table1 Index:
col1 and col2 (2-way index)
col5

Table2 Index:
col4
col8

Table3 Index: 
col3
col7
col9

Table4 Index: 
col10? 

1 个答案:

答案 0 :(得分:1)

评论你的发现:

Table1 Index:
col1 and col2 (2-way index)
col5

将第一个索引更改为(col2, col1)Rule of thumb:首先是等式谓词的索引(s.col2 = 'f'然后是范围s.col1 >= 0)。请不要相信most selective first myth

如果没有执行计划,就无法判断您是否需要col5上的索引(我们不知道使用过的加入算法也不知道加入顺序)。

通常,您希望在from / join子句中每个表提到一个索引。因此,正确的索引可能是(col5, col2, col1)

出于同样的原因,很难说明你对table2的索引建议(加入algo& order?)。

类似地,table3除了无条件子句g.col3 = 1告诉您首先应该将该列放入索引之外。添加col7col9可能有效(取决于加入算法& order;)

table4无处加入但尚未用于排序?那个早上对我来说没有意义。

我写了一篇名为Use The Index,Luke的索引指南。如果您想真正了解什么是最好的,请阅读:http://use-the-index-luke.com/

编辑重新加入算法和订单

原则上,数据库会自动选择最适合您查询的连接算法。 PostgreSQL使用以下三个算法:嵌套循环连接,散列连接或排序/合并连接。除了选择算法之外,处理表的顺序也会影响性能 - 因此数据库会尝试采用最佳算法。

但是:索引会影响关于连接算法和顺序的数据库选择,反之亦然。要真正了解要放置哪些索引,您需要知道哪个算法&订单被使用。不幸的是,这并不能保证最佳性能,因为其他索引可能会使其他连接算法更快,就像数据库首先采用的那样。

找出数据库认为最好的方法是使用explain。然而,解释计划经常重建并且可能在没有通知的情况下改变 - 例如。因为表已经增长,所以另一个连接算法更有意义。这就是为什么你永远不应该优化一个或多或少的空开发数据库。这只是浪费时间。您需要实际数据进行测试。

不幸的是,非常复杂的东西。