MYSQL优化是一个非常大的课题,这篇文章主要介绍了跟MYSQL相关的4个方面,如果想深入研究可以查下相关资料。

一、服务器级别优化

二、操作系统级别优化

三、MYSQL级别优化

四、SQL级别优化

一、服务器级别优化

1.服务器选型

SUN小型机、DELL730xd、HPDL380、IBM3850、云服务等

2. CPU个数、内存大小

大内存,高IO,是现代基于web的数据库的必备

3.磁盘:SAS、SSD、FIO卡

减小寻道时间、旋转时间、传输时间

4. RAID卡电池,RAID级别

WriteBack, ReadAheadNone,Direct,NoWrite Cache if Bad BBU

5.其他:网卡等

二、操作系统级别优化

1. I/O调度策略

NOOP、CFQ、Deadline、Anticipatory

临时生效:echo “dadline” >/sys/block/sda/queue/scheduler

永久生效:/etc/grub.conf中kernel后加elevator=deadline(需要重启)

2. SWAP使用策略

echo"vm.swappiness=10">>/etc/sysctl.conf

https://www.percona.com/blog/2014/04/28/oom-relation-vm-swappiness0-new-kernel/

3.文件系统

ext3、ext4还是使用xfs

4.避免NUMA问题

numactl --interleave=all即是允许所有的处理器可以交叉访问所有的内存

5. /tmp分区

tmpfs  /dev/shm  tmpfs  defaults  00

设置tmpdir=/tmp之后,某些习惯性把文件写到tmp下的人要改一改习惯了,因为这些文件占用的是内存不是磁盘,而且如果不重启的话是一直占用

6. CPU

关闭服务器的节能模式

查看kondemand进程运行情况:

ps -ef |grepkondemand

三、MYSQL级别优化

1.版本的选择,除官方版本外

2.   最重要的参数选项调整

default-storage-engine=innodb

innodb_buffer_pool_size、key_buffer_size

innodb_flush_log_at_trx_commit、sync_binlog

innodb_file_per_table

long_query_time

max_connection

3. Schema设计规范及SQL使用

设计自增列做主键

字段属性尽量都加上NOT NULL约束

尽可能不使用TEXT/BLOB类型

多表联接查询时,结果集小的作为驱动表

复合索引的选择

4.其他建议(pt-toolkit、orzdba等工具使用)

pt-duplicate-key-checker检查并删除重复的索引

pt-index-usage检查并删除使用频率很低的索引

pt-query-digest进行慢查询分析

pt-kill杀掉超长时间的SQL请求

pt-online-schema-change来完成大表的ONLINE DDL需求

pt-table-checksum、pt-table-sync来检查并修复mysql主从复制的数据差异

四、Sql级别优化

案例一:URL列索引优化

T_VIDEO表的SQL操作缓慢,出现性能问题,抓取慢查询,发现主要由大量如下类似的SQL语句执行缓慢:

select … … (这里是表的所有字段)

fromT_VIDEO video0_  where        video0_.VIDEO_PATH=‘http://www.youtube.com/watch?v=ZjxzF3fNQuI‘limit 1;

咨询开发同学,这个是为了确认某条数据是否已经存在,需要查询全部字段并逐一比较。并且表中只有ID列主键,无其他索引。

那么如何缓解这种情况呢?如何确认某条数据是否存在?

制定方案:

1)通过“主键(或者唯一约束)”来判断该行数据是否存在,存在的话直接覆盖更新。

2)坚决不建议逐个字段查询出来一一比较!因为首先,查询语句执行时的Sending Data的时间会加长,当数据量达到一定程度的时候还会产生大量的临时表;其次需要消耗CPU和时间来做比较,性价比不高。

存在问题:

1)存储的URL前n位基本相同或者只有几种,其次URL可能会很长;

2)如果还是使用传统的B-tree索引的话,索引会变得非常大且效率不高

解决方案:

1)大家知道hash索引性能要比B-tree索引好,且基于数字类型的索引性能要比基于字符串的索引好,那么如果我们将URL做一个hash然后在这个hash值上做索引,查询的时候将URL和hash作为where条件,既实现了基于索引的查询,又降低了索引的大小。

2)我们可以使用CRC32函数来实现。

在数据库中建立冗余列URL_CRC,用于存储URL的hash值,这里在插入的时候使用CRC32(“……”)函数,返回值是数字类型

3)在这一列上建立索引

查询的时候使用WHEREURL_CRC=CRC32(“……”)  AND URL=”……”,查询优化器会自动使用索引列URL_CRC,即使有重复值,还可以通过URL列二次筛选

案例二:百万级数据分页

项目中数据量已经动辄百万,且会使用到分页。

开发同学在代码中进行分页一般会这么写:

select *from `table` order by iddesc limit 1000000,50;

可是当数据量到达百万、千万或者更多的时候,很可能会出现分页查询性能下降明显的情况,可能从之前的毫秒到现在的几秒或者几十秒。这是为什么呢?

select * from `table` order by id desc limit100,50;         0.016秒

select * from `table` order by id desc limit1000,50;       0.047秒

select * from `table` order by id desc limit10000,50;      0.094秒

select *from `table` order by iddesc limit 100000,50;    0.43秒

select *from `table` order by iddesc limit 1000000,50;  2.23秒

其实limit在实际执行的时候是“查询1000050行数据,然后丢掉前面的1000000行,返回剩下的50行”,是不是发现了很惊悚的问题了呢?! 浪费了大量的I/O性能啊。

如何优化?

代码级:

程序里维护一个变量,用于记录当前要显示的页的数据起始值,SQL语句中使用这个变量的值;

数据库级(SQL级)

利用覆盖索引

selectid fromFROM `tablle`  order by id desclimit 1000000,50;

或者

SELECT* FROM`table` WHERE id <= (SELECT id FROM `table` ORDER BY id desc LIMIT1000000,1) ORDER BY id desc LIMIT 50;

或者

select* FROM`table` AS t1 JOIN (SELECT id FROM `table` ORDER BY id desc LIMIT1000000,1) ASt2 WHERE t1.id<=t2.id order by t1.id desc limit 50;

原理就是记录住当前页id的最大值和最小值,计算跳转页面和当前页相对偏移,由于页面相近,这个偏移量不会很大,这样的话大大减少扫描的行数。

或者

select* from`table` where id between 1000001 and 1000050;

原理和上面类似,直接定位需要扫描的数据(页),但是如果这个跨度区间内的ID有缺失,那么查询出的数据就小于50条了,这一点一定要注意。

案例三:使用简单SQL去完成复杂功能

原来的执行脚本:

INSERTINTOT_APP_APK_ID_DOWNLOAD

(APK_ID,APP_UPDATE_TIME,DOWNLOAD_NUM)

selecta.APK_ID,a.UPDATE_TIME,IFNULL(b.TOTAL_NUM,0)

from

(selectMAX(id)id,max(UPDATE_TIME) UPDATE_TIME,APK_ID from T_APP GROUP BY APK_ID) as a

LEFTJOIN

T_APP_DOWNLOAD_STATIbon a.id=b.APP_ID;

4000W数据,所需时间15min+

简化SQL语句的重要方法就是采用临时表暂存中间结果,但是,临时表的好处远远不止这些,将临时结果暂存在临时表,后面的查询就在temptable中了,这可以避免程序中多次扫描主表,也大大减少了程序执行中“共享锁”阻塞“更新锁”,减少了阻塞,提高了并发性能。

分拆后执行计划步骤:

1.建立中间表

CREATETABLE `T_APP_TMP` (

`ID`int(11) NOT NULL AUTO_INCREMENTCOMMENT ‘主键‘,

`APP_ID`int(11) NOT NULL DEFAULT‘0‘ COMMENT ‘APK 唯一标识‘,

`UPDATE_TIME`datetime NOT NULLDEFAULT ‘2000-01-01 00:00:00‘ COMMENT ‘APK更新时间‘,

`APK_ID`varchar(150) NOT NULLDEFAULT ‘‘ COMMENT ‘APK 唯一标识‘,

PRIMARY KEY (`ID`),

KEY`idx_app_appid_code` (`APP_ID`)

)ENGINE=InnoDBAUTO_INCREMENT=1DEFAULT CHARSET=utf8 COMMENT=‘应用表‘;

2.将数据插入中间表

INSERTINTOT_APP_TMP(APP_ID,UPDATE_TIME,APK_ID) select MAX(id)id,max(UPDATE_TIME)UPDATE_TIME,APK_ID from T_APP GROUP BY APK_ID;

3.将最终结果插入结果表

INSERT INTOT_APP_APK_ID_DOWNLOAD (APK_ID,APP_UPDATE_TIME,DOWNLOAD_NUM)

selecta.APK_ID,a.UPDATE_TIME,IFNULL(b.TOTAL_NUM,0)

fromT_APP_TMP as a LEFT JOINT_APP_DOWNLOAD_STATI b

ona.APP_ID=b.APP_ID;

4.将中间表删除

DROP TABLET_APP_TMP;

按照这个步骤执行,总共不超过5min钟。

原文:http://www.cnblogs.com/zengkefu/p/5835491.html

mysql+百万+中间表_MYSQL优化相关推荐

  1. mysql百万级去重_mysql优化小技巧之去除重复项(百万级数据)

    mysql优化小技巧之去除重复项(百万级数据) 发布时间:2018-06-11 11:54, 浏览次数:482 , 标签: mysql 说到这个去重,脑仁不禁得一疼,尤其是出具量比较大的时候.毕竟咱不 ...

  2. MySQL分库分表和优化

    第九阶段模块三 分库分表技术之MyCat 1.海量存储问题 1.1 背景描述 随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB.对数据的各种操作也是愈加的困难,传统的关系性数据库已经无 ...

  3. mysql 并发 锁表_MySQL中的锁(表锁、行锁) 并发控制锁

    https://github.com/MrLining/mysql/wiki/MySQL%E4%B8%AD%E7%9A%84%E9%94%81%EF%BC%88%E8%A1%A8%E9%94%81%E ...

  4. mysql list转表_mysql系统表【转】

    MySQL5.7 默认的模式有:information_schema, 具有 61个表: mysqL, 具有31个表: performance_schema,具有87个表; sys, 具有1个表, 1 ...

  5. mysql truncate 大表_MySQL删除大表时潜在的问题(drop table,truncate table)

    case1,删除大表时,因为清理自适应hash索引占用的内容导致的MySQL服务挂起 case2,大表的随意Drop或者truncate导致MySQL服务的挂起 按照本文中的结论就是 MySQL5.6 ...

  6. mysql多张表join_SQL优化之多表join

    关于Join 如上图所示,left join和inner join的取值范围还是有很明显的不同的,看网上不少文章优化left join也不交代上下文环境,直接就是教唆把left join换成inner ...

  7. mysql百万数据分区_mysql百万数据实践-分区

    今天实践下mysql百万级数据分区的影响,首先是产生百万级别的数据量 //创建带分区的数据表 CREATE TABLE `part_person` ( `id` bigint(20) unsigned ...

  8. mysql左驱动表_MySQL多表联表查询驱动表选择

    联表查询做开发的小伙伴会经常使用,但是可以大家都比较少去深入了解MySQL是怎么执行多表联表查询的,比如怎么选择驱动表(第一个被处理的表),是先联表还是说先根据where条件(前提是有where条件) ...

  9. mysql 并发锁表_MySQL锁表的用法,防止并发情况下的重复数据

    早就听说lock tables和unlock tables这两个命令,从字面也大体知道,前者的作用是锁定表,后者的作用是解除锁定.但是具体如何用,怎么用,不太清楚.今天详细研究了下,总算搞明白了2者的 ...

最新文章

  1. C语言数组作为传入参数
  2. Labview通过RS422通讯接口PC与下位机通信
  3. 2021杨雪洋高考成绩查询,青春由磨砺而岀彩,人生因奋斗而升华 ——我校隆重举行2021届高考备考动员暨学业水平考试表彰大会...
  4. 【最小生成树】水箱(P5952)
  5. android查询所有照片,Android查询外部存储中所有照片
  6. 五大数据库理念,读懂亚马逊云科技的数据库布局
  7. Python中fastapi关于异常或者错误的处理
  8. java求出遍历二叉树的路径,102. 二叉树的层序遍历
  9. opencv之在图像上绘制标记---drawMarker
  10. 【Python计量】自相关性(序列相关性)的检验
  11. python写入文件
  12. 风口来了第二期——电子科学与技术专业现状和前景介绍分享
  13. C#毕业设计——基于C#+asp.net+SQL server的物料管理系统(ERP)设计与实现(毕业论文+程序源码)——物料管理系统(ERP)
  14. meltdown linux检测,Linux操作系统已拥有自动化的Spectre/Meltdown检查器
  15. cmd模式下用cd命令进入其他盘或者文件夹
  16. 产品经理与程序员之间的孽缘发展历程
  17. 什么是防雷接地,防雷接地工程的作用和重要意义
  18. 友盟 推特分享错误
  19. UCenter Home
  20. 二狗子的志愿者故事20210121

热门文章

  1. 远程办公首日企业通讯软件崩溃、紧急扩容,云办公怎么了?
  2. 微服务落地,我们在考虑什么?| 技术头条
  3. python复制列表元素_Python学习教程:Python列表赋值,复制,深拷贝及5种浅拷贝详解...
  4. 最小覆盖模型matlab_数学规划模型的matlab求解 非线性最小二乘lsqnonlin
  5. 动态游标for循环_【【动图算法】(动态规划篇):最长回文子串
  6. ETL异构数据源Datax_datax-web简述_09
  7. 检测到会话cookie中缺少HttpOnly属性
  8. 第八篇:Spring Boot整合Thymeleaf_入门试炼04
  9. Windows 环境 Jenkins集成构建SonarQube
  10. elementui 按钮 表单_element UI实现表格中添加开关控制按钮