运行 10.8.8-MariaDB-log
我对比较网站有一个非常复杂的查询。
本质上
SELECT <columns> FROM <tables>
JOIN <derived table 1 for first comparison>
JOIN <derived table 2 for first comparison>
JOIN <derived table 1 for second comparison>
JOIN <derived table 2 for second comparison>
运行时间 < 0.1 秒
如果我把它改成
SELECT <columns> FROM <tables>
JOIN <derived table 1 for first comparison>
JOIN <derived table 2 for first comparison>
JOIN <derived table 1 for second comparison>
JOIN <derived table 2 for second comparison>
JOIN <derived table 1 for third comparison>
JOIN <derived table 2 for third comparison>
需要10多秒
索引是可靠的,除了 ID 参数值之外,每次比较创建派生表的 sql 都是相同的。唯一改变的是它们的数量。
我怀疑有一些缓冲区/缓存需要增加一点?🤷♂️
是的,我可以完全重写页面/sql,通过一种非常不同的机制来完成它,但如果我可以通过简单的配置更改来解决这个问题,那么考虑到机器上的可用资源,我更愿意这样做。时间很短。
我知道这可能是一个 x/y 问题,但我希望这里有一个容易实现的目标,经验丰富的人能够立即识别出来。
FWIW - 在黑暗中拍摄 - 我尝试将这三个的大小增加四倍,但没有什么区别:
join_buffer_size = 32M (to 128M)
sort_buffer_size = 4M (to 16M)
read_rnd_buffer_size = 4M (to 16M)
谢谢
直到大约
STRAIGHT_JOIN
。STRAIGHT_JOIN
类似JOIN
,只是它告诉查询优化器按照您创建查询的方式运行查询。为什么这很重要?基本上,阶乘。
优化器知道许多巧妙的技巧来最好地猜测最佳执行计划,但本质上,执行计划的复杂性遵循阶乘模式。
在我原来问题的例子中,我有 14 个表。870 亿个选项
然后是16张桌子。2万亿个选项
就像我说的,优化器并不那么愚蠢,它可以修剪很多并采取很多捷径,但我认为这些数字确实说明了查询中大量表的问题。问题不在于查询运行需要多长时间,而在于优化器需要多长时间来确定如何运行它。
举个例子。我现在正在测试/摆弄一个查询,其中有 18 个表。
除了将我所有的s 替换为s之外,我实际上什么也没做。
JOIN
STRAIGHT_JOIN
结果?我的查询时间从 1.65s 下降到0.002s。
这种构造对性能来说非常糟糕,因为所有“派生表”都没有索引:
所以,是的,添加更多
JOIN
对性能来说是很糟糕的。不,你无法调整自己的方式来解决问题。(调整可能会有所帮助,但这不是真正的解决方案。)
让我们
SELECT
一起看一个更完整的SHOW CREATE TABLEs
;我们也许能够提供一些建设性的建议。