Ste*_*ott 5 sql t-sql sql-server azure-sql-database
我在某些依赖于子查询的查询上遇到了一个奇怪的问题。它们运行得快如闪电,直到我在子查询中使用 UNION 语句。然后他们就无休无止地跑,我10分钟后就给了。我现在描述的场景不是我一开始的场景,但我认为它消除了很多可能的问题,但却产生了同样的问题。因此,即使这是一个毫无意义的问题,请耐心等待!
\n\n我有一张桌子:
\n\ntblUser - 100,000 rows\ntblFavourites - 200,000 rows\nRun Code Online (Sandbox Code Playgroud)\n\n如果我执行:
\n\nSELECT COUNT(*) \nFROM tblFavourites \nWHERE userID NOT IN (SELECT uid FROM tblUser); \nRun Code Online (Sandbox Code Playgroud)\n\n\xe2\x80\xa6 然后它运行不到一秒钟。但是,如果我修改它以使子查询具有 UNION,它将运行至少 10 分钟(在我放弃之前!)
\n\nSELECT COUNT(*) \nFROM tblFavourites \nWHERE userID NOT IN (SELECT uid FROM tblUser UNION SELECT uid FROM tblUser); \nRun Code Online (Sandbox Code Playgroud)\n\n这是毫无意义的改变,但它应该产生相同的结果,我不明白为什么它应该花更长的时间?
\n\n将子查询放入视图中并调用它具有相同的效果。
\n\n有什么想法吗?我正在使用 SQL Azure。
\n\n问题解决了。请参阅下面我的回答。
\n\nUNIONDISTINCT实际上是对组合数据集中的所有字段进行操作。它会过滤掉最终结果中的重复内容。
是否已Uid编入索引?如果不是,查询引擎可能需要很长时间:
如果重复项不是问题(并且使用IN意味着它们不会),那么使用UNION ALL它可以消除昂贵的排序/过滤步骤。
事实证明,问题是由于索引之一... tblFavourites 包含 tblUser 中主键 (uid) 的两个外键:
userId
otherUserId
Run Code Online (Sandbox Code Playgroud)
两列具有相同的定义和相同的索引,但我发现在原始查询中将 userId 替换为 otherUserId 解决了问题。
我跑:
ALTER INDEX ALL ON tblFavourites REBUILD
Run Code Online (Sandbox Code Playgroud)
...然后问题就消失了。现在查询几乎立即执行。
我不太了解 Sql Server/Azure 幕后发生的事情......但我只能想象它是损坏的索引或其他什么?我经常更新统计数据,但这没有效果。
谢谢!
- - 更新
以上并不完全正确。它确实解决了大约 20 分钟的问题,然后又恢复了。我已经与 Microsoft 支持人员联系了几天,问题似乎与 tempDB 有关。他们最终正在研究解决方案。
| 归档时间: |
|
| 查看次数: |
18011 次 |
| 最近记录: |