首页 > 代码库 > 关于sql 的一些性能讨论
关于sql 的一些性能讨论
SQL Server会将执行过的语句存入高速缓存中,因此理论上说使用带参数的语句会比使用常量的语句要快(因为每次语句相同,减少了语句分析和执行计划选择)。但如果参数赋予不同值时,返回的行数差异很大,这时选择相同的执行计划反而使一些查询变的异常慢。下面是f_parent_cateid赋予不同常量时得到的执行计划,它们各不相同,但如果使用参数方式,执行计划只会使用其中一种,取决于哪个被先执行。之前有测试过,如果A执行计划作为唯一选择时,f_parent_cateid=111将需要执行3分多钟(事实上选择B执行计划只要很短时间)。
2,Update时,无论更新的字段值是否改变,语句都会造成数据实际被修改(数据在硬盘上迁移),因此要避免无须修改的字段写在Update语句中,特别是那些索引组成字段(尤其是聚集索引组成字段)。
3,在一次查询中,并不是一张表只用一个索引,有时会采用两个索引连接得到结果。执行计划可以查看
4, 对于两张相对比较大的表,并且表行的数相近,执行计划有可能会选择嵌套循环连接两张表(原因不知),这时查询速度会异常的缓慢,比如两张100万级别的表,嵌套循环连接就相当于10000亿次(O(n^2))的比较(要出结果至少1小时以上)。当SQL Server错误的选择表连接方式时,应该将语句中的inner join强制改为inner hash join,直接使用Hash连接(O(n)),得到结果只要10到30秒。总之,如果遇到查询很慢时,应该优先查看一下是否是因执行计划选择错误造成的。
5,SQL Server(2008 及以前)目前还不支持跳跃式使用索引(Oracle支持),对于组合索引,必须按照索引中出现的字段顺序使用索引。如:由A和B组成的组合索引,如果A没出现在WHERE语句中(仅B),即使A的值只有两三种,也都无法使用上该组合索引。遇到这种情况可以考虑人为的加上辅助条件(加A条件),然后通过多次查询(取决A可能的值)返回结果。
6,如果两个表可以合在一张表,尽量将其合并,一个查询中越多表连接,就意味着越多的索引查找。尽管列较宽的表,索引查找成本会更高些(因为一页(8KB)存储的行数变少),但比起更多的索引查找,其成本还是小的多。
7,对于使用参数的语句或使用常量的语句,应保证其值类型与表中字段类型一致,否则有可能使用不上索引或分区列。对于整型常量,SQL Server默认认为是32位整型(即使64位的SQL Server也一样)。
关于sql 的一些性能讨论