为什么 SQL Server ce 中的 Select * FROM Table where ID NOT IN (list of int ids) 查询很慢?
这个问题在 sql server ce 中很常见
我在所有字段上都有索引。
也是相同的查询,但使用 ID IN(int ids 列表)非常快。
我尝试将查询更改为 OUTER Join 但这只会让情况变得更糟。 那么关于为什么会发生这种情况以及如何解决这个问题有什么提示吗?
well this problem is general in sql server ce
i have indexes on all the the fields.
also the same query but with ID IN ( list of int ids) is pretty fast.
i tried to change the query to OUTER Join but this just make it worse.
so any hints on why this happen and how to fix this problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
ammoQ 是对的,索引对您的查询没有多大帮助。根据 ID 列中值的分布,您可以通过指定选择而不是不选择哪些 ID 来优化查询。如果你最终请求超过~25%的表索引无论如何都不会被使用,因为对于非聚集索引(这是SQL CE在内存可用的情况下支持的唯一索引类型),扫描表会更便宜。否则(如果查询实际上是选择性的),您可以使用要选择的 ID 范围重写查询(如果 SQL CE 支持“union all”,则“union all”可能比“or”更好地组合范围,不确定)
ammoQ is right, index does not help much with your query. Depending on distribution of values in your ID column you could optimise the query by specifying which IDs to select rather than not to select. If you end up requesting say more than ~25% of the table index will not be used anyway though because for nonclustered indexed (which is the only type of indexes which SQL CE supports if memory serves) it would be cheaper to scan the table. Otherwise (if the query is actually selective) you could re-write query with ID ranges to select ('union all' may work better than 'or' to combine ranges if SQL CE supports 'union all', not sure)
这不是SQL Server CE 中的问题,而是整个数据库的问题。
OPERATION IN 是可控制的,而 NOT IN 是不可控制的。
这是什么意思?
Search ARGument Able,这意味着 DBMS 引擎可以利用索引,对于 Non Search ARGument Ablee 则不能使用索引。
解决方案可能是使用过滤器语句来删除这些 ID
更多信息请参阅 Peter Gulutzan 的《SQL 性能调优》。
This is not a problem in SQL Server CE, but overall database.
The OPERATION IN is sargable and NOT IN is nonsargable.
What this mean ?
Search ARGument Able, thies mean that DBMS engine can take advantage of using index, for Non Search ARGument Ablee the index can't be used.
The solution might be using filter statement to remove those IDs
More in SQL Performance Tuning by Peter Gulutzan.
那是因为索引对于这种查询并没有真正的帮助,所以数据库必须进行全表扫描。如果查询(由于某种原因)比简单的“SELECT * FROM TABLE”慢,请改为执行此操作并过滤程序中不需要的 ID。
编辑:根据您的评论,我认识到您使用子查询而不是列表。因此,有三种可能的方法可以做到这一点(希望其中一种更快):
原始声明:
替代方案 1:
替代方案 2:
替代方案 3:(丑陋且难以理解,但如果其他一切都失败了......)
That's because the index is not really helpful for that kind of query, so the database has to do a full table scan. If the query is (for some reason) slower than a simple "SELECT * FROM TABLE", do that instead and filter the unwanted IDs in the program.
EDIT: by your comment, I recognize you use a subquery instead of a list. Because of that, there are three possible ways to do the same (hopefully one of them is faster):
Original statement:
Alternative 1:
Alternative 2:
Alternative 3: (ugly and hard to understand, but if everything else fails...)