使用嵌套选择语句优化 MySQL 查询?
Posted
技术标签:
【中文标题】使用嵌套选择语句优化 MySQL 查询?【英文标题】:Optimizing MySQL query with nested select statements? 【发布时间】:2013-09-04 22:37:55 【问题描述】:我对 mysql 数据库具有只读访问权限,我需要循环以下查询大约 9000 次,每次使用不同的 $content_path_id。我从一个 PERL 脚本中调用它,该脚本从文件中提取“$content_path_id”。
SELECT an.uuid FROM alf_node an WHERE an.id IN
(SELECT anp.node_id FROM alf_node_properties anp WHERE anp.long_value IN
(SELECT acd.id FROM alf_content_data acd WHERE acd.content_url_id = $content_path_id));
以这种方式编写,每次查询都需要 永远 (每次大约需要 1 分钟)。如果我不需要的话,我真的宁愿不要等待 9000 多分钟才能完成。有没有办法加快这个查询?也许通过加入?我目前的 SQL 技能生疏得令人尴尬……
【问题讨论】:
为什么不在一个表中包含所有$content_path_id
,用alf_content_data
连接该表(在content_url_id
上),然后用alf_node_properties
连接结果,然后用@ 连接结果987654327@?
EXISTS
可能比IN
更快。见***.com/questions/14190788/…
谢谢尼赞。不幸的是,我只有对数据库的只读访问权限,所以我无法添加表。
【参考方案1】:
试试这个 Laurence 解决方案的扩展,它用一个额外的 JOIN 替换长长的 OR 列表:
Select
an.uuid
From alf_node an
Join alf_node_properties anp
On an.id = anp.node_id
Join alf_content_data acd
On anp.long_value = acd.id
Join (
select "id1" as content_path_id union all
select "id2" as content_path_id union all
/* you get the idea */
select "idN" as content_path_id
) criteria
On acd.content_url_id = criteria.content_path_id
我已经使用了上面的 SQL Server 语法,但你应该可以很容易地翻译它。
【讨论】:
【参考方案2】:这是一个使用连接的等效查询。这取决于表上定义的索引如何执行。
如果您的 Perl 接口具有预准备语句的概念,您可以通过准备一次并执行 9000 个不同的绑定来节省一些时间。
您还可以通过使用大的 acd.content_url_id In ($content_path_id1, $content_path_id2, ...)
子句构建一个查询来节省时间
Select
an.uuid
From
alf_node an
Inner Join
alf_node_properties anp
On an.id = anp.node_id
Inner Join
alf_content_data acd
On anp.long_value = acd.id
Where
acd.content_url_id = $content_path_id
【讨论】:
谢谢 Laurence:这似乎有点,但不是很多,更快。我想知道是否可以通过将所有 9000 个查询作为“OR”放在“where”行中并将其作为一个巨型查询执行来使其更快。这会有帮助吗? 如果alf_content_data (content_url_id, acd.id)
上没有索引,那么它几乎肯定会使其更快。我对 ($content_path_id1, ..) 等中的 `acd.content_url_id 的建议与此等价。
抱歉——我没有注意到您原始答案中的“acd.content_url_id In”位。这确实有助于进行较小的测试,因此现在正在运行全尺寸测试。谢谢!
整个更长的查询在不到 2 分钟的时间内完成,所以我可以确认“acd.content_url_id IN”位实际上大大加快了速度。再次感谢劳伦斯!以上是关于使用嵌套选择语句优化 MySQL 查询?的主要内容,如果未能解决你的问题,请参考以下文章