查询性能优化

查询性能优化

1.基本原则:优化数据访问

1)请求了不需要的数据  
    提取超过需要的列  
    多表连接时提取所有列  
2)mysql检查了过多的数据  
    三大指标:执行时间、检查的行数、返回的行数  
    检查的行和返回的行:      
        通常不对应,比如连表查询;  
    检查的行和访问类型  
        mysql会在3中情况下实用where子句,从最好到最坏依次是:        
            对索引查找应用where子句来消除不匹配的行,发生在存储引擎层。  
            使用覆盖索引(extra为“using index”)来避免访问行,并且从索引取得数据后过滤掉不匹配的行。发生在服务器层,但是他不需要从表中读取行。  
            从表中检索出数据,然后过滤掉不匹配的行(在extra列中是“using where”)。发生在服务器端并且要求在过滤之前读取这些行。              
        如果发现访问的数据行数很大,而生成的结果中数据行很少,那么可以尝试更复杂的修改:
            使用覆盖索引,它存储了数据,所以存储引擎不会去获取完整的行  
            更改架构;  
            重写复杂的查询,让mysql的优化器可以以优化的方式执行它。  

2.重构查询的方式

1)复杂查询和多个查询  
    衡量两个之间的关系,是把复杂查询多个化,还是多个查询一个3化  
2)缩短查询  
    举个例子:
    巨大查询 delete from messages where created < data_sub(now(),interval 3 month);  
    应用伪代码查询替代
        rows_affected = 0  
        do {
            rows_affected = do_query(
                "delete from messages where created < date_sub(now(),interval 3 month) limit 10000"
            )
        }   
    对于一个高效的查询来说,一次删除10000行数据的任务已经足够大。足够短的任务对服务器的影响最小。在delete语句中加入休眠语句也是一个好主意,它可以分摊负载,并且减少锁住资源的时间。  

3.分解联接

将多表联查分解为小查询,在客户端进行合并。  
优点:  
    1)缓存的效率更高。  
    2)对myisam表来说,每个表一个查询可以更有效的利用表锁,因为查询会锁住单个表较短时间,而不是把所有表长时间锁住。  
    在应用程序段进行连接可以方便的扩展数据库,把不同的表放在不同的服务器上面。  
    3)查询本身会更高效。  
    可以减少多余的行访问。连接查询是非正则化,反复的访问同一行数据。在应用程序端进行连接意味着对每行数据只会访问一次。  
    4)从某种意义上,可以认为这种方式是手工执行哈希连接,而不是mysql内部执行连接操作时采用的嵌套循环算法。哈希连接效率更高。  
场景(在程序端进行连接效率更高):
    1)可以缓存早期查询的大量数据。  
    2)使用了多个myisam表。  
    3)数据分布在不同的服务器上  
    4)对于大表使用in()替换连接。  
    5)一个连接引用了同一个表很多次。

4.查询执行基础知识

mysql执行查询的一般性过程:
    1)客户端将查询发送到服务器。  
    2)服务器检查查询缓存。如果找到了,就从缓存中返回结果,否则进行下一步。  
    3)服务器解析,预处理和优化查询,生成执行计划。  
    4)执行引擎调用存储引擎api执行查询。  
    5)服务器将结果发送回客户端。   

你可能感兴趣的:(查询性能优化)