通往性能优化的天堂-地狱 JOIN方法说明
2007-06-27 09:45:04 来源:WEB开发网hash join一般都用于大数据量的操作,例如join中某个表的数据达到一定程度或者无法一次加载到内存,另外如果你的关联字段在两个join表中都不能够命中索引,也是使用hash join来处理。因此一般情况下,hahs join处理代价非常高,是数据库服务器内存和CPU的头号杀手之一,尤其是涉及到分区(数据量太大导致内存不够的情况,或者并发访问很高导致当前处理线程无法获得足够的内存,那么数据量不是特大的情况下也可能需要进行分区),为了尽快的完成所有的分区步骤,将使用大量异步的I/O操作,因此期间单一一个线程就可能导致多个磁盘驱动器出于忙碌状态,这很有可能阻塞其它线程的执行。
使用inner hash join或者option (hash join)强制使用hash join方法。
建议
三种join方法,都是拥有两个输入。优化的基本原则:1. 避免大数据的hash join,尽量将其转化为高效的merge join、nested loop join。可能使用的手段有表结构设计、索引调整设计、SQL优化,以及业务设计优化。例如冗余字段的运用,将统计分析结果用service定期跑到静态表中,适当的冗余表,使用AOP或类似机制同步更新等。2. 尽量减少join两个输入端的数据量。这一点比较常犯的毛病是,条件不符合SARG(光这一点就有很多高超的技巧可以发挥),在子查询内部条件给的不充分(SQL过于复杂情况下SQL Server查询优化器经常犯傻,写在子查询外部的条件不会被用在子查询内部,影响子查询内部的效率或者是跟子查询再join时候的效率)。另外也是设计、业务端尽量限制这两个输入的数据量了。
关于业务设计方面的优化,参考以前写的一篇post:系统分析设计 一个JOIN问题解决方案的感想 重视业务分析设计。
补充(2007.06.27):关于SQL Server 2005
大致看了下SQL Server 2005,执行计划的显示确实有一些不一样,但主要部分或者说原理上是差不多的,不会有多少偏差。上面的示例SQL,在tableB上面使用非聚集索引时,SQL Server 2005的执行计划图如下:
一个主要的不同点是SQL Server 2000下面Bookmark Lookup操作,在2005下面显示成一个RID Lookup操作 + 一个Nested Loops操作实现,其实这也是很好理解的,可以说这样显示执行计划更合理一点,让你一看到这个操作,就知道它是通过一个循环机制到tableB中获取实际数据。
另外一点是,将鼠标移动到执行计划的图标上面后,弹出的提示信息的一些改变,例如2005里面会显示每个操作的输出列表(output list),而我上面的文章中基本都使用“输出数据结构”这样一个词汇在表达。通过查看output list,你更能明白RID Lookup(Bookmark Lookup)这样的操作存在的理由了。
最后,2005里面可以将图形显示的执行计划保存下来,以后可以打开再以图形方式进行查看分析,这个在2000下面是不行的,2000只能保存执行计划的文本。这样一些小功能对于分析SQL性能非常有用,在图形界面上的分析更直观。
更多精彩
赞助商链接