如何提高 MySQL 服务器性能..?

Abd*_*naf 4 mysql performance index optimization mysql-5.5

作为 MySQL DBA,大多数时候我们应该优化性能不佳的 MySQL 服务器。

现在我的问题是从哪里开始,就像我们需要找出很多事情一样

1.Find the duplicate indexes.
2.Find unused indexes on the basis of selectivity.
3.Monitor the Server Parameters(What should be important parameters).
4.Execute MySQL Server performance tuning script.
5.Slow logs
Run Code Online (Sandbox Code Playgroud)

那么检查服务器的顺序应该是什么,应该监视/分析的确切内容应该是什么,以提高性能。

Rol*_*DBA 7

查找重复索引

早在 2012 年 1 月,@gbn 回答了一个关于重复索引的问题,他在其中展示了来自Ronald Bradford 博客的2 个视图。我将这两个视图合并为一个查询以显示重复索引,如下所示:

SELECT
    ndx1.TABLE_SCHEMA,ndx1.TABLE_NAME,
    CASE 
        WHEN ndx1.COLUMNS = ndx2.COLUMNS
        AND (ndx1.IS_UNIQUE = ndx2.IS_UNIQUE) 
        THEN GREATEST(ndx1.INDEX_NAME, ndx2.INDEX_NAME) 
        ELSE ndx1.INDEX_NAME 
    END REDUNDANT_INDEX_NAME,
    GROUP_CONCAT(DISTINCT 
        CASE 
            WHEN ndx1.COLUMNS = ndx2.COLUMNS
            AND (ndx1.IS_UNIQUE = ndx2.IS_UNIQUE) 
            THEN LEAST(ndx1.INDEX_NAME, ndx2.INDEX_NAME) 
            ELSE ndx2.INDEX_NAME 
        END
    ) INDEX_NAME 
FROM
(
    SELECT
        TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,
        IF(NON_UNIQUE, 'NO', 'YES') IS_UNIQUE,
        GROUP_CONCAT(CONCAT('`',COLUMN_NAME,'`')
        ORDER BY IF(INDEX_TYPE='BTREE',SEQ_IN_INDEX,0), COLUMN_NAME
        ) COLUMNS 
    FROM
        information_schema.STATISTICS 
    GROUP BY
        TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,NON_UNIQUE 
) ndx1 INNER JOIN 
(
    SELECT
        TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,
        IF(NON_UNIQUE, 'NO', 'YES') IS_UNIQUE,
        GROUP_CONCAT( 
        CONCAT('`',COLUMN_NAME,'`') 
        ORDER BY IF( INDEX_TYPE = 'BTREE'
        , SEQ_IN_INDEX
        , 0) 
        , COLUMN_NAME
        ) COLUMNS 
    FROM
        information_schema.STATISTICS 
    GROUP BY
        TABLE_SCHEMA,TABLE_NAME,INDEX_NAME,INDEX_TYPE,NON_UNIQUE 
) ndx2
ON ndx1.TABLE_SCHEMA = ndx2.TABLE_SCHEMA
AND ndx1.TABLE_NAME = ndx2.TABLE_NAME 
AND ndx1.INDEX_NAME != ndx2.INDEX_NAME
AND ndx1.INDEX_TYPE = ndx2.INDEX_TYPE 
AND CASE 
WHEN ndx1.COLUMNS = ndx2.COLUMNS
AND (ndx1.IS_UNIQUE = 'NO'
OR ndx1.IS_UNIQUE = ndx2.IS_UNIQUE)
THEN TRUE 
WHEN ndx1.INDEX_TYPE = 'BTREE' -- when BTREE 
AND INSTR(ndx2.COLUMNS, ndx1.COLUMNS) = 1
AND ndx1.IS_UNIQUE = 'NO'
THEN TRUE 
ELSE FALSE 
END 
GROUP BY ndx1.TABLE_SCHEMA,ndx1.TABLE_NAME,REDUNDANT_INDEX_NAME
;
Run Code Online (Sandbox Code Playgroud)

显然,每个分组中列数最少的索引需要被剔除

根据选择性查找未使用的索引。

在我的开发者时代,我没有对未使用的索引做太多事情。我尝试只制作与以下子句匹配的必要索引:

  • 在哪里
  • 通过...分组
  • 订购者

如果您必须通过查找未使用的索引来清理数据库,请阅读以下内容:

监控服务器参数(哪些应该是重要的参数)

这只是要监视的全局状态值类型的示例。请阅读有关服务器状态变量的 MySQL 文档

执行 MySQL Server 性能调优脚本

最直接的脚本是 mysqltuner.pl 拿来运行就可以了

# wget mysqtuner.pl
# perl mysqltuner.pl
Run Code Online (Sandbox Code Playgroud)

慢日志

慢日志在低流量环境中非常有用。不幸的是,我已经看到太多以下情况

考虑到这种情况,当大量查询需要公共表时,我的查询以极快的速度独立工作。

恕我直言,慢查询日志实际上对您没有好处,因为它记录了被视为慢的已完成查询。您真正想要做的是在长时间运行的行为中捕获长时间运行的查询。因此,我建议使用pt-query-digest将进程列表(或 tmpdump)用于运行 amok 的查询。我在 2011 年 12 月写了一篇关于如何编写 crontab 作业脚本的帖子,该作业使用mk-query-digest(可以插入 pt-query-digest)每 20 分钟轮询一次进程列表