使用随机分量优化和索引查询
Posted
技术标签:
【中文标题】使用随机分量优化和索引查询【英文标题】:Optimizing and indexing query with random component 【发布时间】:2015-07-24 01:02:43 【问题描述】:我继承的代码中有以下查询:
SELECT a.row2, a.row3
FROM table1 a
JOIN table2 b ON a.row1 = b.row1
WHERE b.row2 IN (
SELECT id
FROM table3
WHERE id IN ($table3_ids)
)
ORDER BY RAND();
[a.row1 是 table1 的主键]
几个问题:
有没有更有效的方法来构建这个查询?
我已经在 (row1, row2, row4) 的 table1 中有一个索引;为(row1,row2,row3)创建一个单独的索引是多余的,还是我应该用(row1,row2,row3,row4)上的索引替换前者?
从另一端,我已经在 table2 的 (row1, row2, row3) 上有一个索引;因为看起来我需要在 table2 中为 (row1, row2) 建立一个索引来优化这个查询,所以包含一个简单地排除同一个表中不同索引中的单个元素的索引是否是多余的?
这是我不清楚查询引擎如何知道哪个索引合适的地方;解析查询时,是否首先检查表中的匹配索引?
最后(可能是最简单的回答),我正在使用以下语法添加索引:
ALTER TABLE table_name ADD KEY (row1, row2, row3);
创建索引后,我将手动重命名每个索引。是否可以在命令中包含索引的名称?
非常感谢!
【问题讨论】:
也许你的意思是column
而不是row
?
【参考方案1】:
这是您的查询:
SELECT a.row2, a.row3
FROM table1 a JOIN
table2 b
ON a.row1 = b.row1
WHERE b.row2 IN (SELECT id FROM table3 WHERE id IN ($table3_ids))
ORDER BY RAND();
我认为最好的索引是:table2(row2, row1)
和 table1(row1, row2, row3)
和 table3(id)
。您可以将row4
添加到table1
索引中,但这并没有什么不同。此外,您将列命名为“行”真的很奇怪——对我来说这会导致认知失调。
实际上,除非您的查询中有拼写错误,否则您可以省略 table3
并执行以下操作:
WHERE b.row2 IN ($table3_ids)
请注意,in ($table3_ids)
需要字符串替换。这不能参数化。这引入了 SQL 注入的危险。
如果您的结果集超过几百行,可能有几千行,那么order by
将很重要。如果是这种情况,您可能需要尝试不同的方法来获得所需的结果。
【讨论】:
非常感谢...在我减少查询时使用“行”而不是“列”对我来说是一个“大脑放屁”...他们说的太糟糕了!跨度> @Tom 。 . .我无法弄清楚为什么我对你的问题有这种模糊的不安,直到我意识到名字是原因;)【参考方案2】:对 Gordon 的回答的一些补充:
ALTER TABLE reference 在语法中显示可选的index_name
。
IN ( SELECT ... )
效率极低;把它变成JOIN
:
SELECT a.row2, a.row3
FROM table1 a
JOIN table2 b ON a.row1 = b.row1
JOIN table3 c ON b.row2 = c.id
WHERE c.id IN ($table3_ids) )
ORDER BY RAND();
或者...
SELECT a.row2, a.row3
FROM table1 a
JOIN table2 b ON a.row1 = b.row1
WHERE b.row2 IN ($table3_ids) )
ORDER BY RAND();
(需要c
的可能原因:您正在过滤c
中缺少的ID?)
ORDER BY RAND()
很昂贵。除非您也有LIMIT
,否则它基本上无法优化。
【讨论】:
谢谢,@Rick ...您提出的第二种方式是我如何阅读 Gordon 的建议,即(并且正确地使用“column”而不是“row”): SELECT a.column2, a.column3 FROM table1 a JOIN table2 b ON a.column1 = b.column1 WHERE b.column2 IN ($table3_ids) ORDER BY RAND() 实际查询是: SELECT a.large_image, a.title FROM arta JOIN gallery_artwork ga ON a。 id = ga.artwork_id WHERE ga.galleries_id IN($question_marks) ORDER BY RAND()以上是关于使用随机分量优化和索引查询的主要内容,如果未能解决你的问题,请参考以下文章