关闭

查询优化 sql

1097人阅读 评论(0) 收藏 举报

 

查询1:
DECLARE @d datetime
SET @d = getdate()
SELECT top 1000 * FROM product WHERE CONTAINS(name,'男上装') OR CONTAINS(text,'男上装')
SELECT datediff(ms,@d,getdate())
SET @d = getdate()
SELECT * FROM product WHERE CONTAINS(name,'男上装') OR CONTAINS(text,'男上装')
SELECT datediff(ms,@d,getdate())

结果1:(总数:14条)
14条数据用时3610(这是使用了top 1000后)
14条数据用时266  (这是没有使用top 1000的)

查询2:
DECLARE @d datetime
SET @d = getdate()
SELECT top 1000 * FROM product WHERE CONTAINS(name,'公司') OR CONTAINS(text,'公司')
SELECT datediff(ms,@d,getdate())
SET @d = getdate()
SELECT * FROM product WHERE CONTAINS(name,'公司') OR CONTAINS(text,'公司')
SELECT datediff(ms,@d,getdate())

结果2:(总数:165949条)
1000条数据用时4233(这是用了top 1000后)
165949条数据用时8330(这是没用top 1000后)

 

 

楼主的查询使用了 OR 条件, 这个查询大致上会这样生成这样的执行计划:
1. 执行两句:
SELECT top 1000 * FROM product WHERE CONTAINS(name,'男上装')
SELECT top 1000 * FROM product WHERE CONTAINS(text,'男上装')
2. 对结果做一个join

这样就涉及取两表join联接的算法了
有top 的情况下, 一般使用的是嵌套循环, 没有top的情况下, 多半使用的是哈希联接

嵌套循环使用的搜索方法是:
将一个联接输入用作外部输入表(显示为图形执行计划中的顶端输入),将另一个联接输入用作内部(底端)输入表。外部循环逐行处理外部输入表。内部循环会针对每个外部行执行,在内部输入表中搜索匹配行。

很显然, 如果匹配的数据很少的话(准确地说匹配的数据在扫描顺序的尾部, 匹配的数据越少, 发生这种情况的可能性越高), 那么扫描势必会遍历完整个表, 这样的效率显然不高.
而哈希联接不存在这种问题

所以你会发觉, 匹配的数据量少的情况下, TOP 的执行效率反而低.

 

 

OPTION 子句
指定应在整个查询中使用所指定的查询提示。每个查询提示只能指定一次,但允许指定多个查询提示。用该语句只可能指定一个 OPTION 子句。查询提示影响语句中的所有运算符。如果主查询中涉及 UNION,则只有涉及 UNION 运算符的最后一个查询可以有 OPTION 子句。如果一个或多个查询提示导致查询优化器不生成有效计划,则产生 8622 错误。

 

注意  由于查询优化器通常为查询选择最优执行计划,所以建议只把 <join_hint>, <query_hint> 和 <table_hint> 作为经验丰富的数据库管理员的最终手段。


语法
[ OPTION ( < query_hint > [ ,...n ] ) ]

< query_hint > ::=
    {    { HASH | ORDER } GROUP
    | { CONCAT | HASH | MERGE } UNION
    | { LOOP | MERGE | HASH } JOIN
    | FAST number_rows
    | FORCE ORDER
    | MAXDOP number
    | ROBUST PLAN
    | KEEP PLAN
    | KEEPFIXED PLAN
    | EXPAND VIEWS
    }

 

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:308887次
    • 积分:4966
    • 等级:
    • 排名:第5912名
    • 原创:181篇
    • 转载:0篇
    • 译文:0篇
    • 评论:21条
    文章分类