我是数据库世界的新手,所以希望根据以下查询获得有关创建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?
答案 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
告诉您首先应该将该列放入索引之外。添加col7
和col9
可能有效(取决于加入算法& order;)
table4无处加入但尚未用于排序?那个早上对我来说没有意义。
我写了一篇名为Use The Index,Luke的索引指南。如果您想真正了解什么是最好的,请阅读:http://use-the-index-luke.com/
编辑重新加入算法和订单
原则上,数据库会自动选择最适合您查询的连接算法。 PostgreSQL使用以下三个算法:嵌套循环连接,散列连接或排序/合并连接。除了选择算法之外,处理表的顺序也会影响性能 - 因此数据库会尝试采用最佳算法。
但是:索引会影响关于连接算法和顺序的数据库选择,反之亦然。要真正了解要放置哪些索引,您需要知道哪个算法&订单被使用。不幸的是,这并不能保证最佳性能,因为其他索引可能会使其他连接算法更快,就像数据库首先采用的那样。
找出数据库认为最好的方法是使用explain
。然而,解释计划经常重建并且可能在没有通知的情况下改变 - 例如。因为表已经增长,所以另一个连接算法更有意义。这就是为什么你永远不应该优化一个或多或少的空开发数据库。这只是浪费时间。您需要实际数据进行测试。
不幸的是,非常复杂的东西。