概述
怎样编写性能比較高的SQL查询语句呢?两个方法:创建合理的索引。书写高效的SQL语句
索引的基本原理
索引分为聚集索引和非聚集索引。
一个表仅仅能创建一个聚集索引和N个非聚集索引,这句话的由来主要是因为索引的原理决定的。
数据库中的一张表不论你创建不创建索引,或者,不论你创建那种类型的索引。其在硬盘上的存储是一样的,那么,创建索引和不创建索引,或者,创建聚集索引和非聚集索引的差别在什么地方呢?
其差别是表内数据在内存的存在形式。对于没有创建索引的表,其载入到内存里时。就仅仅有数据块。对于有聚集索引的表,其载入到内存时,会形成一棵树,且叶子节点上就是详细的数据。对于非聚集索引的表(没有聚集索引时)。其载入内存时,真实数据为一个独立的块,其索引会形成一个索引树。索引数据的叶子节点相应的是真实数据块的rowid。对于既有非聚集索引,又有聚集索引的表,其载入到内存时,会形成两棵树。详细的数据和聚集索引树在一起。非聚集索引独自有一棵树。此时须要注意,其叶子节点中存放的时聚集索引的index,然后,通过聚集索引的index再去,聚集索引树中找到详细的数据。
这个就是为什么一个表仅仅能有一个聚集索引。能够有多个非聚集索引的原理。
怎样知道我们的SQL查询语句运行时性能的好坏呢?
我们写一个SQL查询语句。怎么样才干知道这个SQL查询语句是好的还是坏的?
一种方法,我们大家都知道。直接在SQL Server的查询器中运行,然后,其运行状态栏会给出我们对应的结果,如:运行时间(秒);另一种方法,通过运行set statistics io on,开启资源消耗信息,运行set statistics time on,开启运行时间,开启这两个功能后,我们再次运行sql语句时。其结果视图旁边的消息视图内,会出现对应的结果。另一种方式就是使用SQL Server Profiler工具(工具—SQL Server Profiler)。帮助我们监听运行的SQL语句的运行情况。这样的方式更适用于我们在程序中无法提取SQL语句的情况。
如何创建合理的索引?
通过上面的方法。我们能够知道我们的SQL语句的好坏,对于坏的SQL,我们要想法设法的进行对应的改变,可是。对于坏的SQL语句。我们在优化的时候,总得要知道其问题出在了哪里吧。不能说我就那么的改了,所以。此时,我们须要了还有一个工具,帮助我们分析,即:运行计划视图(查询—显示运行的查询计划),通过运行计划。可知道我们SQL语句在运行查询的时候,使用了还是没有使用索引。在这里介绍3中查询的方式:table scan,index scan。index seek。
table scan就是全表扫描,直接在真实的数据块中进行所有扫描。index scan就是在索引树上进行全扫描,此时假设是聚集索引,就会直接得到对应的数据(叶子上就是详细的数据),假设是非聚集索引,则须要获得叶子上对应的聚集索引键,然后,再依据聚集索引键在聚集索引树中找到对应的真实数据;index scan就是索引树上的搜索。这样的方式的实现跟其内部的原理有关,由于这个是树,所以,依据一些算法(二叉等等)能够高速的定位到详细的数据。这个也分为聚集和非聚集,在这里不再赘述。
通过运行计划,我们能够知道。我们的SQL语句在那块没有使用索引。然后。我们能够改SQL语句,也能够创建对应的索引,这里须要知道,并非使用了索引就一定块。假设你的数据很的小,假设你创建的索引很的多,那么,可能会存在这样的情况:不如全表索引的块。
所以,在优化我们的SQL时,我们尽量往已有的索引上靠拢。实现不行了,那么,依据数据量的多少,我们看看,是否须要再创建对应的索引。
怎么样才干书写高效的SQL查询语句?
上面一块内容我们知道了,我们的SQL语句应该尽可能的向已有的索引靠拢,那么。假设才干使用到已有的索引呢?你可能会说,我们多创建一些索引不即可了嘛,实在不行每一个列都是一个索引,这样不就能够使用到了索引了嘛,依照你说的这样的情况,我们姑且不考虑其他。就觉得SQL语句运行的时候,使用了索引就是快。可是,我想说的是。及时你每一个列上都创建上索引。也不见得你写的SQL语句在运行的时候就是使用到了index seek。为什么呢?由于系统在分析你的SQL语句时,无法找到一个合理的index seek的运行计划,那么。怎么样写我们的SQL语句,才干够使系统经过分析后,得到的运行计划里使用到了index seek呢?怎么样写我们的SQL语句才干够得到最优的运行计划呢?
1、查询列的优化
用到表中的那个列就select谁,不要select * ,除非你每一个列都使用。由于select * 和select 全部列是一样的
2、where查询条件的优化
不要对条件列进行对应的操作,如:在列上使用函数,列进行数据类型的转换。列上使用參数运算符(filed + 'aaa')。在列上使用不可參数化的条件(like '%a',not……,or……等),这些都会使索引的实现大大折扣。或者直接就丧失
3、其他
不要使用游标,能够使用集合条件查询代码游标;使用exists取代count(*)进行数据存在与否的验证
总结
索引多了不见得好。没有索引不见得不好;索引的有无。是依据详细的数据量来说的。该列是否要建立索引,是依据这个列在查询时作为条件查询的比重;好的SQL语句,不仅要向索引靠拢。也要屏蔽不必要的数据和运行次数。