整理的mysql优化内容
1,当只要一行数据时使用 LIMIT 1
如果明确只取一条数据,要加上limit 1;
2,避免 SELECT *,根据需要获取字段
应该养成一个需要什么就取什么的好的习惯。
3,使用 ENUM 而不是 VARCHAR
ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。
4,把IP地址存成 UNSIGNED INT
进行选择合适并且占用空间小的字段,特别是需要建索引的字段更需要尽量减少字段的长度减少表的大小以提高查询的速度。
如IP地址尽量使用无符号整数int unsigned来保存,对状态和类型上的标识尽量使用tinyint unsigned,如果使用varchar则尽量长度不要超过16个字节。
//将IP转换为整数$ip_num = ip2long('211.157.144.20');
//将整数转换为IP$ip = long2ip('3718090772');
5,随机去5条数据
SELECT * FROM User ORDER BY rand() LIMIT 5; (避免)
5 rows in set (15.33 sec)
select * from User as t1 join (select round(rand() * (select max(user_id) from User)) as user_id ) as t2 where t1.user_id > t2.user_id order by t1.user_id asc limit 5;
5 rows in set (0.00 sec)
但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。
6,尽量减少表连接查询,最好是单表查询
7,避免全表扫描
对查询进行优化,应尽量避免全表扫描,首先应考虑在where及order by 涉及的列上建立索引。
8,左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整。
9,尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录
10,知识点--explain
mysql解释语句
type显示的是访问类型,是较为重要的一个指标,结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般来说,得保证查询至少达到range级别,最好能达到ref。
explain select * from User where num > 5 and status = 'normal' limit 2;
+----+-------------+-------+------+---------------+--------+---------+-------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+--------+---------+-------+--------+-------------+
| 1 | SIMPLE | User | ref | status | status | 258 | const | 164739 | Using where |
+----+-------------+-------+------+---------------+--------+---------+-------+--------+-------------+
1 row in set (0.00 sec)
id:查询序列号;
select_type:查询类型,常见的取值有 SIMPLE (简单表,即不使用表连接或者子查询)、 PRIMARY (主查询,即外层的查询)、 UNION ( UNION 中的第二个或者后面的查询语句)、 SUBQUERY (子查询中的第一个 SELECT )等;
table:输出结果集的表;
type:扫描方式,all表示全表扫描,表示表的连接类型,性能由好到差的连接类型为
system > const > eq_ref > ref > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > all
possible_keys:可能使用的索引
key:实际使用的索引
key_len:索引字段长度
rows:该SQL扫描了多少行,可能得到的数据行
Extras:额外信息,如排序方式等
mysql> explain select * from User where update_ts < '2016-01-01' limit 10 ;
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
| 1 | SIMPLE | User | range | update_ts | update_ts | 4 | NULL | 164739 | Using where |
+----+-------------+-------+-------+---------------+-----------+---------+------+--------+-------------+
mysql> explain select * from User where year(update_ts) < 2016 limit 10 ;
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | User | ALL | NULL | NULL | NULL | NULL | 329478 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+--------+-------------+
同样的情形也会发生在对数值型字段进行计算的时候:
mysql> explain select user_id from User where total=4;
+----+-------------+-------+------+---------------+-------+---------+-------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------+---------+-------+------+--------------------------+
| 1 | SIMPLE | User | ref | total | total | 5 | const | 3308 | Using where; Using index |
+----+-------------+-------+------+---------------+-------+---------+-------+------+--------------------------+
1 row in set (0.00 sec)
mysql> explain select user_id from User where total/2=2;
+----+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
| 1 | SIMPLE | User | index | NULL | total | 5 | NULL | 331815 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+--------+--------------------------+
1 row in set (0.00 sec)
整理的mysql优化内容的更多相关文章
- MySQL优化面试
原则:尽量使用整型表示字符串 存储IP INET_ATON(str),address to number INET_NTOA(number),number to address MySQL内部的枚举类 ...
- MySQL优化/面试,看这一篇就够了
原文链接:http://www.zhenganwen.top/articles/2018/12/25/1565048860202.html 作者:Anwen~链接:https://www.nowcod ...
- mysql 优化知识点
附录: https://www.nowcoder.com/discuss/150059?type=0&order=0&pos=13&page=0 本文概要 概述 为什么要优化 ...
- 3万字总结,Mysql优化之精髓
本文知识点较多,篇幅较长,请耐心学习 MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降. ...
- 【Mysql 优化 6】mysql优化的内容和思路
根据最近做mysql优化,以及参照的官方文档的一些知识点,总结一下,如何下手去优化mysql 数据库.PS:更多可能是我个人的笔记总结记录,仅供参考 一.优化的内容 可以优化的内容,从范围的大小,可以 ...
- MYSQL优化之碎片整理
MYSQL优化之碎片整理 在MySQL中,我们经常会使用VARCHAR.TEXT.BLOB等可变长度的文本数据类型.不过,当我们使用这些数据类型之后,我们就不得不做一些额外的工作--MySQL数据 ...
- MySQL优化整理
一.SQL优化 1.show status查看各种sql的执行频率 SHOW STATUS 可以根据需要显示 session 级别的统计结果和 global级别的统计结果. 显示当前sessi ...
- 整理的网上的MySQL优化文章总结
MySQL优化 Linux优化 IO优化 调整Linux默认的IO调度算法. IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调 ...
- MySQL优化概述
一. MySQL优化要点 MySQL优化是一门复杂的综合性技术,主要包括: 1 表的设计合理化(符合 3NF,必要时允许数据冗余) 2.1 SQL语句优化(以查询为主) 2.2 适当添加索引(主键索引 ...
随机推荐
- 【BZOJ-3033】太鼓达人 欧拉图 + 暴搜
3033: 太鼓达人 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 204 Solved: 154[Submit][Status][Discuss] ...
- BZOJ2440 [中山市选2011]完全平方数
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- Linux修改密码passwd用法
语法: passwd [-k] [-l] [-u [-f]] [-d] [-S] [username] 必要参数:-d 删除密码-f 强制执行-k 更新只能发送在过期之后-l 停止账号使用-S 显示密 ...
- Jenkins企业版与CloudBees
Jenkins企业版由CloudBess提供! 参考 https://www.cloudbees.com/ http://www.infoq.com/cn/news/2012/01/cloudbees ...
- 对接微信红包时:CA证书出错,请登录微信支付商户平台下载证书
今天在对接微信支付的微信红包发放时,出现““CA证书出错,请登录微信支付商户平台下载证书”的错误,特此记录一下: 如果你也在对接微信红包,并且你也在这个页面上下载了demo,再就是你也参照了里面的文档 ...
- Android成长日记-数据存储之SQLite[2]
Part one: 首先看这样一段代码 SQLiteDatabase db=openOrCreateDatabase("SQLDemo.db", MODE_PRIVATE,null ...
- 为什么 SharedPreferences 可以直接 调用,前面却没有对象
获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两 ...
- git远程分支
1. 同步远程服务器上的数据到本地 git fetch origin 2. 添加远程分支 git remote add teamone git://git.tram1.ourcompany.com 添 ...
- codevs 3143 二叉树的序遍历
传送门 Description 求一棵二叉树的前序遍历,中序遍历和后序遍历 Input 第一行一个整数n,表示这棵树的节点个数. 接下来n行每行2个整数L和R.第i行的两个整数Li和Ri代表编号为i的 ...
- w3m常用快捷键
H 显示帮助 q 退出,会有提示的 j,k,l,h 移动光标 J/K 向下/向上滚屏 T 打开一个新标签页 Esc-t 打开所有标签页,供你选择,使用jk来上下移动 U ...