简单的 SQL 嵌套选择查询不再起作用

Posted

技术标签:

【中文标题】简单的 SQL 嵌套选择查询不再起作用【英文标题】:Simple SQL nested select query no longer working 【发布时间】:2012-05-09 09:39:46 【问题描述】:

我有一个相对简单的查询,通常需要不超过 10 秒才能返回。如下:

SELECT personid 
FROM vw_has_copyright 
WHERE (Orderid IN (SELECT orderid 
                   FROM orders WHERE eventid = 1234)) 
GROUP BY personid 
ORDER BY personid

现在它只是在我运行此查询时挂起。如果我运行select orders.orderid from orders where orders.eventid = 1234 - 然后将此查询生成的列表与select personid from vw_has_copyright where Orderid in (*my list here...*) 一起使用,它可以正常工作。

那么为什么它不再适用于嵌套选择查询呢?看起来很奇怪,但我不确定如何调试它?提前致谢!!

---编辑---

相当尴尬的是,问题在于我没有正确维护我的索引。由于我的订单表索引上的高度碎片化,查询突然停止工作,但是在重建和重组它们之后,查询现在又可以工作了!故事的寓意 - 照顾你的数据库!

【问题讨论】:

哪个 DBMS? PostgreSQL?甲骨文? DB2? 什么版本的 SQL? (mysql、MS SQL Server、Oracle?)我会考虑刷新表统计信息和/或重新编译视图(假设 vw_ 表示视图) 执行计划是什么,上次执行索引维护和更新统计是什么时候? 如果它突然“挂起”,可能是锁定问题。其他一些事务修改了 vw_has_copyright 或 orders 表并阻止了您的选择 简直不敢相信 - 但我的 SQL Server 代理维护计划一直处于非活动状态(一定有一段时间),因为我的索引上有大量碎片。我刚刚重建和重组了相关索引,现在一切正常! 【参考方案1】:

IN 非常棘手,特别是在通常有大量记录的订单表上。我建议将其更改为 EXISTS 甚至是常规加入。

Here 是一个很好的链接,解释了这 3 个操作数之间的区别

【讨论】:

感谢您提供的信息 - 虽然从技术上讲这不是解决我的问题的方法,但我现在正在阅读,知道它很有用!【参考方案2】:

试试这样的

SELECT CopyRight.personid 
FROM vw_has_copyright CopyRight
     Inner Join orders order on order.orderid = CopyRight.Orderid
WHERE  order.eventid = 1234
GROUP BY CopyRight.personid 
ORDER BY CopyRight.personid

【讨论】:

【参考方案3】:

您应该定期执行索引维护和统计信息更新,以确保查询始终如一地执行。

检查执行计划以查看 SQL Server 是否执行任何意外(表扫描与索引查找)也很重要。

【讨论】:

以上是关于简单的 SQL 嵌套选择查询不再起作用的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套查询从表列表/多个表中选择 - MS SQL

使用 Group By 选择无法正常工作

优化多个嵌套选择的 SQL 查询

如何优化这个嵌套的 SQL 查询

从嵌套 SQL 查询中选择 TOP 或 GROUP BY 排名数据

EF Core 嵌套 Linq 选择导致 N + 1 个 SQL 查询