zoukankan      html  css  js  c++  java
  • MySQL学习之查询优化(一)

    Slow Query Basics: Optimize Data Access

    查询太慢的一个最基本的原因就是:处理的数据太多了。

    1. 看看你的应用获取的数据是否大于它需要的数据

    2. 看看MySQL Server是否分析了大于它需要的数据

    常见的错误

    1.Fetching more rows than needed

    2. Fetching all columns from a multitable join

    3. Fetching all columns

    4. Fetching the same data repeatedly

    重建查询的方法

    分解查询(任务)

    比如清理表数据,如果一次清理得太多,那么很多行会被锁住,挡住其他查询等。所以把DELETE的任务分解成小块来执行能很明显提升性能。

    mysql> DELETE FROM messages WHERE created < DATE_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")
    } while rows_affected > 0

    分解联表

    如:

    mysql> SELECT * FROM tag
    -> JOIN tag_post ON tag_post.tag_id=tag.id
    -> JOIN post ON tag_post.post_id=post.id
    -> WHERE tag.tag='mysql';

    可以分解成下面的:

    mysql> SELECT * FROM tag WHERE tag='mysql';
    mysql> SELECT * FROM tag_post WHERE tag_id=1234;
    mysql> SELECT * FROM post WHERE post.id in (123,456,567,9098,8904);

    这样的优点有:

    • 缓存更有效
    • 减少锁表竞争
    • 方便数据库部署在不同的服务器上面
    • 单个的SQL效率更高,如IN()要比联表来得快
    • 减少access的行,因为联表本身是反范式的,会重复查很多数据
    • 类似于hash联表的技术

    查询执行的基础

    1. 客户端向服务端发送SQL语句

    2. 服务端先找缓存,如果有直接返回结果,否则进入下一步

    3. 服务端编译、预处理和优化SQL

    4. 查询执行引擎通过调用存储引擎的API来执行SQL

    5. 服务端返回结果

    The MySQL Client/Server Protocol

    Mysql的C/S协议是half duplex的,就是说,服务端可以发送也可以接受信息,但是不能同时发送和接受信息

    客户端一次请求只发送一个包,max_allowed_packet 决定了服务端能接受的最大的包,如果你的请求太大了,服务器会报错并不再接受客户端的请求。

    相反的,服务端能返回很多包给客户端,客户端必须要接受全部的服务端结果,而不能接受一部分后告诉服务端我不再需要了。这就是为什么SQL里加上LIMIT很重要。

    也就是说,客户端不是从服务端“拉”数据,而是服务端把数据“推“过来,这个过程是被动的,不能被客户端停止的。

    1 <?php
    2 $link = mysql_connect('localhost', 'user', 'p4ssword');
    3 $result = mysql_query('SELECT * FROM HUGE_TABLE', $link);
    4 while ( $row = mysql_fetch_array($result) ) {
    5 // Do something with result
    6 }

    举个例子,上面的代码看起来好像是你需要数据的时候再去fetch,但事实上,数据在调用mysql_query的时候已经在缓存里了,调用mysql_fetch_array时只是在和缓存对话。

    Query states

    使用SHOW FULL PROCESSLIST

    Sleep: 等待客户端的请求

    Query: 执行请求或是向客户端推送数据

    Locked: 等待服务端给一个锁表的权限

    Analyzing and statistics: 检查存储引擎的数据和优化查询

    Copying to tmp table [ on disk ]: 将查询结果放入缓存表,UNION, GROUP BY都有可能导致

    Sorting result

    Sending data

    The Query Cache

    The Query Optimization Process

    Reordering joins: 联表的顺序会被优化

    Converting OUTER JOINs to INNER JOINs

  • 相关阅读:
    Django-model基础
    web框架
    django-MTV
    我与前端之间不得不说的三天两夜之jQuery
    vertical-align和line-height的深入应用
    我与前端之间不得说的三天两夜之css基础
    mysql数据库从删库到跑路之mysql:视图、触发器、事务、存储过程、函数
    我与前端之间不得不说的三天两夜之html基础
    hdu2206 IP地址的计算
    get方式中文乱码解决方法
  • 原文地址:https://www.cnblogs.com/hugmyloneliness/p/3654717.html
Copyright © 2011-2022 走看看