zoukankan      html  css  js  c++  java
  • MySQL数据库优化(一)

    1.1.1. 慢查询日志
    当查询超过一定的时间没有返回结果的时候,才会记录到慢查询日志中。默认不开启。
    采样的时候手工开启。可以帮助我们找出执行慢的 SQL 语句
    查看慢 SQL 日志是否启用(on 表示启用):
    show variables like 'slow_query_log';
    查看执行慢于多少秒的 SQL 会记录到日志文件中
    show variables like 'long_query_time';
    可以使用模糊搜索,查看所有含有 query 的变量信息
    show variables like '%query%';

    1.1.2. 修改 l mysql 配置参数
    my.ini(Linux 下文件名为 my.cnf),查找到[mysqld]区段,增加日志的配置。
    Windows 下路径一般为 C:ProgramDataMySQLMySQL Server 5.7my.ini",可以在
    启动参数中查看使用的是那个配置文件。

    常用的参数详解:
    #--是否开启慢查询日志
    slow_query_log=1
    # --指定保存路径及文件名,默认为数据文件目录,
    slow_query_log_file="bxg_mysql_slow.log"
    # --指定多少秒返回查询的结果为慢查询
    long_query_time=1
    # --记录所有没有使用到索引的查询语句
    log_queries_not_using_indexes=1
    #--记录那些由于查找了多于 1000 次而引发的慢查询
    min_examined_row_limit=1000
    # --记录那些慢的 optimize table,analyze table 和 alter table 语句
    log_slow_admin_statements=1
    #--记录由 Slave 所产生的慢查询
    log_slow_slave_statements=1

    datadir=C:/ProgramData/MySQL/MySQL Server 5.7Data --数据文件目录
    注意:修改以下参数,需要重新启动数据库服务才会生效。

    1.1.3. 命令行修改慢查询配置
    命令行修改配置方式不需要不重启即可生效,但重启之后会自动失效。
    set global slow_query_log=1;
    set global slow_query_log_file='bxg_mysql_slow.log';
    set long_query_time=1;
    set global log_queries_not_using_indexes=1;
    set global min_examined_row_limit=1000;
    set global log_slow_admin_statements=1;
    set global log_slow_slave_statements=1;
    其他参数可通过以下命令查阅:
    show variables like '%query%';
    show variables like '%slow%';

    1.1.4. 慢日志格式

    时间、主机信息、执行信息、执行时间、执行内容

    1.1.5. 查询缓存
    Query Cache 会缓存 select 查询,安装时默认是开启的,但是如果对表进行 INSERT,
    UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE 等操作
    时,之前的缓存会无效并且删除。这样一定程度上也会影响我们数据库的性能。所以对一
    些频繁的变动表的情况开启缓存是不明智的。还有一种情况我们测试数据库性能的时候也
    要关闭缓存,避免缓存对我们测试数据的影响。
    show VARIABLES like '%cache%';

    查看缓存命中情况
    select count(*) FROM test;
    select count(*) FROM test;
    show status like '%qcache%';

    关闭缓存有两种放法,一种临时的,一种永久的。临时的直接在命令行执行
    set global query_cache_size=0;

    set global query_cache_type=0; --如果配置文件中为关闭缓存的话,不能通过命令开启缓存
    永久的修改配置文件 my.cnf ,添加下面的配置即可。
    query_cache_type=0
    query_cache_size=0
    另外,我们还可以通过 sql_no_cache 关键字在 sql 语句中直接禁用缓存,在开启缓存
    的情况下我们对 sql 语句做一些改动
    Select sql_no_cache count(*) from pythonlearn.lianjia; -- 不缓存
    Select sql_cache count(*) from pythonlearn.lianjia; -- 缓存(也可以不加,默认缓存已经开启了)

    1.1.6. 准备测试数据
    创建测试表

    -- 用户表
    CREATE TABLE `person` (
    `id` bigint(20) unsigned NOT NULL,
    `fname` varchar(100) NOT NULL,
    `lname` varchar(100) NOT NULL,
    `age` tinyint(3) unsigned NOT NULL,
    `sex` tinyint(1) unsigned NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8
    --用户部门表
    CREATE TABLE `department` (
    `id` bigint(20) unsigned NOT NULL,
    `department` varchar(100) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8
    -- 用户住址表
    CREATE TABLE `address` (
    `id` bigint(20) unsigned NOT NULL,
    `address` varchar(100) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=INNODB DEFAULT CHARSET=utf8

    创建存储过程,用于批量添加测试数据
    delimiter $$
    drop procedure if exists generate;
    CREATE DEFINER=`root`@`localhost` PROCEDURE `generate`(IN num INT)
    BEGIN

    DECLARE chars VARCHAR(100) DEFAULT
    'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    DECLARE fname VARCHAR(10) DEFAULT '';
    DECLARE lname VARCHAR(25) DEFAULT '';
    DECLARE id int UNSIGNED;
    DECLARE len int;
    set id=1;
    DELETE from person;
    WHILE id <= num DO
    set len = FLOOR(1 + RAND()*10);
    set fname = '';
    WHILE len > 0 DO
    SET fname = CONCAT(fname,substring(chars,FLOOR(1 + RAND()*62),1));
    SET len = len - 1;
    END WHILE;
    set len = FLOOR(1+RAND()*25);
    set lname = '';
    WHILE len > 0 DO
    SET lname = CONCAT(lname,SUBSTR(chars,FLOOR(1 + RAND()*62),1));
    SET len = len - 1;
    END WHILE;
    INSERT into person VALUES (id,fname,lname, FLOOR(RAND()*100),
    FLOOR(RAND()*2));
    set id = id + 1;
    END WHILE;
    END $$
    delimiter $$
    drop procedure if exists genDepAdd;
    CREATE DEFINER=`root`@`localhost` PROCEDURE `genDepAdd`(IN num INT)
    BEGIN
    DECLARE chars VARCHAR(100) DEFAULT '行政技术研发财务人事开发公关推广营销咨询客服
    运营测试';
    DECLARE chars2 VARCHAR(100) DEFAULT '北京上海青岛重庆成都安徽福建浙江杭州深圳温
    州内蒙古天津河北西安三期';
    DECLARE depart VARCHAR(10) DEFAULT '';
    DECLARE address VARCHAR(25) DEFAULT '';
    DECLARE id int UNSIGNED;
    DECLARE len int;
    set id=1;
    WHILE id <= num DO
    set len = FLOOR(2 + RAND()*2);
    set depart = '';
    WHILE len > 0 DO
    SET depart = CONCAT(depart,substring(chars,FLOOR(1 + RAND()*26),1));
    SET len = len - 1;
    END WHILE;
    set depart=CONCAT(depart,'部');
    set len = FLOOR(6+RAND()*18);
    set address = '';
    WHILE len > 0 DO
    SET address = CONCAT(address,SUBSTR(chars2,FLOOR(1 + RAND()*33),1));
    SET len = len - 1;
    END WHILE;
    INSERT into department VALUES (id,depart);
    INSERT into address VALUES (id,address);
    set id = id + 1;
    END WHILE;
    END $$
    为了提高速度,可以暂停事务。测试添加 100 万随机数据,大概 600s 左右时间。
    -- 停掉事务
    set autocommit = 0;
    -- 调用存储过程
    call generate(1000000);
    -- call genDepAdd(1000000);
    -- 重启事务
    set autocommit = 1;

    对比 MyIsam:当创建表时选择 MyIsam 格式,插入数据会很慢,仅仅 3000 条数据就
    需要 2 分钟的时间,由此可见 MyIsam 和 InnoDB 的差距还是很大的。另外在执行过程中可以发现 MyIsam 插入的数据可以在表中实时看到,而 InnoDB 做了事务最终一次提交,
    所以数据不能实时看到,只有存储过程全部执行完成后才可以看到数据

    未完待续

    学习时的痛苦是暂时的 未学到的痛苦是终生的
    本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。
  • 相关阅读:
    vs2008将 win32项目改为console项目
    python——pandas技巧(处理dataframe每个元素,不用for,而用apply)
    leetcode计划
    初识Flask——基于python的web框架
    开展论文研究——推荐系统
    c++如何按照map的value进行排序?
    sklearn决策树应用及可视化
    黑客可远程控制!微软紧急修补2个新漏洞,以下系统版本都受影响
    高通推出新的智能手表芯片,为安卓系统注入新的活力
    美国宇航局向有创意的科技小企业支付5100万美元
  • 原文地址:https://www.cnblogs.com/juanxincai/p/12050877.html
Copyright © 2011-2022 走看看