知识大全 一句T-SQL语句引发的思考 转帖

Posted 语句

篇首语:笛里谁知壮士心,沙头空照征人骨。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 一句T-SQL语句引发的思考 转帖相关的知识,希望对你有一定的参考价值。

一句T-SQL语句引发的思考 转帖  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  关于MS SQLSERVER索引优化问题:   有表Stress_test(id int key char( ))   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]id 上有普通索引;   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]key 上有簇索引;   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]id 有有限量的重复;   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]key 有无限量的重复;     现在我需要按逻辑与查询表中key= Az AND key= Bw AND key= Cv 的id     求教高手最有效的查询语句     测试环境   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Hardware:P + M+ G   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Sofare:windows server (Enterprise Edition)+Sqlserver +sp a     [$nbsp][$nbsp]首先我们建立一个测试的数据 为使数据尽量的分布和随即 我们通过RAND()来随机产生 个随机数再组合成一个字符串 首先插入的数据是 条记录 然后在循环插入到 条记录   [$nbsp][$nbsp][$nbsp]因为是随机产生的数据 所以如果你自己测试的数据集和我测试的会不一样 但对索引的优化和运行的效率是一样的   [$nbsp][$nbsp][$nbsp]下面的 //测试脚本 是产生测试数据的脚本 你可以根据需要修改 @maxgroup @maxLoop的值 比如测试 百万的记录可以:     [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxgroup=   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxLoop=     如果要测试 千万     [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxgroup=   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]Select @maxLoop=     所以如果你的SERVER或PC比较慢 请耐心等待   (在我的PC上运行的速度是插入 百万条的时间是 m 插入 千八百万条的时间是 m 重新建立INDEX的时间是 m)         作为一般的开发人员很容易就想到的语句     [$nbsp][$nbsp][$nbsp] 语句     [$nbsp][$nbsp][$nbsp][$nbsp]select a [id] from   [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = Az ) a   [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = Bw ) b   [$nbsp][$nbsp][$nbsp][$nbsp](select distinct [id] from stress_test where [key] = Cv ) c   [$nbsp][$nbsp][$nbsp][$nbsp]where a id = b id and a id = c id     [$nbsp][$nbsp][$nbsp] 语句     [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]select [id]   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]from stress_test   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where [key]= Az or [key]= Bw or [key]= Cv   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]group by id having(count(distinct [key])= )     [$nbsp][$nbsp][$nbsp] 语句     [$nbsp][$nbsp][$nbsp][$nbsp]SELECT distinct a [id] FROM stress_test AS a stress_test AS b stress_test AS c   [$nbsp][$nbsp][$nbsp][$nbsp]WHERE a [key]= Az AND b [key]= Bw AND c [key]= Cv   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]AND a [id]=b [id] AND a [id]=c [id]     但作为T SQL的所谓 高手 可能会认为这种写法很 土 也显得没有水平 所以会选择一些子查询和外连接的写法 按常理子查询的效率是比较高的     [$nbsp][$nbsp][$nbsp] 语句     [$nbsp][$nbsp][$nbsp][$nbsp]select distinct [id] from stress_test A where   [$nbsp][$nbsp][$nbsp][$nbsp]not exists (   [$nbsp][$nbsp][$nbsp][$nbsp]select from   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp](select Az as k union all select Bw union all select Cv ) B   [$nbsp][$nbsp][$nbsp][$nbsp]left join stress_test C on C id=A id and B [k]=C [key]   [$nbsp][$nbsp][$nbsp][$nbsp]where C id is null)     [$nbsp][$nbsp][$nbsp] 语句     [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]select distinct a id from stress_test a   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where not exists   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]( select * from keytb c   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where not exists   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]( select * from stress_test b   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]where   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]b id = a id   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]and   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp]c kf = b [key]   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp][$nbsp])   [$nbsp][$nbsp][$nbsp][$nbsp][$nbsp])     我们先分析这几条语句(针对 千 百万条数据进行分析)     请大家要特别留心Estimated row count的值     语句 :从执行规划中我们可以看出 MSSQLSERVER选择的索引优化非常有规律 先通过CLUSTERED INDEX筛选出符合[KEY]= Az 条件的ID 然后进行HASH MATCH 在找出ID相等的 依次类推最终检索到符合所有条件的记录 中间的Estimated row count的值都不大     语句 :从执行规划中我们可以看出 是先通过CLUSTERED INDEX筛选出符合 [key]= Az or [key]= Bw or [key]= Cv 符合所有条件的ID 然后分组进行 次HASH MATCH 所有的ID 我们可以看出Estimated row count的值是越来越少 从最初的 到最后排序的只有     语句 :从执行规划中我们可以看是非常复杂的 是先通过 组 通过CONSTANT SCAN和NON CLUSTERED INDEX检索出符合 A ID=C ID AND [key]= ** 的记录 组 然后分组进行外键匹配 再将 组的数据合并 排序 然后再和一个NON CLUSTERED INDEX检索出的记录集进行外键匹配 我们可以看出MSSQLSERVER会对所有的记录( 千万条)记录进行分组 Estimated row count的值是 所以这句T SQL的瓶颈是对 千万条记录进行分组     语句 :从执行规划中我们可以看和语句 有相似之处 都要对所有的记录( 千万条)记录进行分组 所以这是检索的瓶颈 而且使用的索引都是NON CLUSTERED INDEX     语句 从执行规划中我们可以看出 先通过CLUSTERED INDEX检索出符合[Key]= Az 的记录集 然后进行HASH MATCH和SORTS 因为数量少所以是非常会的 在和通过NON CLUSTERED INDEX检索[KEY]= Bw 的记录进行INNER JOIN 在和通过CLUSTERED INDEX检索[KEY]= Cv 的记录进行合并 最后是对 百万条数据进行分组检索 如果是 列 我们可以看出Estimated row count的值是递增 越来越大 最后的分组检索的Estimated row count的值是 E+ 这已经形成巨大的瓶颈     我们可以先测试一下小的数据量( 条)     大家可以下面测试脚本的     [$nbsp][$nbsp][$nbsp]Select @maxgroup=   [$nbsp][$nbsp][$nbsp]Select @maxLoop=        | 语句 语句 语句 语句 语句 |   | 万( 列) ms ms ms ms ms   | 万( 列) ms ms ms ms ms       从测试的的数据来看 语句 的效率是最高的 几乎没有花费时间 而语句 的效率只能说是一般 如果测试到这里就结束了 我们可以毫不犹豫的选择语句 : ( 继续进行下面的测试     我们测试百万条以上的记录    先对 百万条记录进行测试(选取 列)    先对 百万条记录进行测试(选取 列)    对 千万条数据测试(选取 列)    对 千万条数据测试(选取 列)     统计表      | 语句 语句 语句 语句 语句 |   | 百万( 列) % % % % %   | 百万( 列) % % % % %   | 千万( 列) % % % % %   | 千万( 列) % % % % %   统计表      | 语句 语句 语句 语句 语句 |   | 百万( 列) ms ms ms ms ms   | 百万( 列) ms ms ms ms ms   | 千万( 列) ms ms ms ms ms   | 千万( 列) ms ms ms ms m以上     测试总结 (我们可以比较关注 语句 和语句 )    在 百万条记录的情况下 语句 是最快的 但在 千万条记录下是最慢的 这说明INDEX的优化一定的情况下 数据量不同 检索的效率也是不同的 我们 cha138/Article/program/Oracle/201311/18861

相关参考

知识大全 SQL Server 数据库管理常用的SQL和T-SQL语句[3]

SQLServer数据库管理常用的SQL和T-SQL语句[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 SQL Server 数据库管理常用的SQL和T-SQL语句[2]

SQLServer数据库管理常用的SQL和T-SQL语句[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 SQL Server 数据库管理常用的SQL和T-SQL语句[1]

SQLServer数据库管理常用的SQL和T-SQL语句[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来

知识大全 及 引发的思考 急

韩国对中国传统文化掠夺的全部事件及引发的思考急!某报道:中国人说:“韩国人说孙中山是韩国人。”但是韩国人民的80%不知道孙中山是谁,知道也没有这样说,也就是说那句话是编的。对中国传统文化现状的思考对中

知识大全 用一句话形容,一个人要告诉你一件事,而迟迟不告诉你,的这种心情的语句

用一句话形容,一个人要告诉你一件事,而迟迟不告诉你,的这种心情的语句着急我要告诉你一件事歌词歌曲名:我要告诉你一件事歌手:Asos专辑:变态少女ASOS我要告诉你一件事趁你还没睡着以前 我要告诉你一件

知识大全 在java中,如果不是在循环语句中怎么用break跳到指定语句

在java中,如果不是在循环语句中怎么用break跳到指定语句?break除了可循环语句,和switch-case语句中,还可指明它要跳出的代码快,并从紧跟该快的下一句执行,如:breakBolckL

知识大全 使用T-SQL开始SQL代理工作

使用T-SQL开始SQL代理工作  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  系统的存储进程s

知识大全 T-SQL 存储过程创建 PDF 格式文件报表

T-SQL存储过程创建PDF格式文件报表  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  This

知识大全 SQL Server 管理常用的SQL和T-SQL

SQLServer管理常用的SQL和T-SQL  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  S

知识大全 在T-SQL中实现Oracle的MINUS集合运算符

在T-SQL中实现Oracle的MINUS集合运算符  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!