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优化内容的更多相关文章

  1. MySQL优化面试

    原则:尽量使用整型表示字符串 存储IP INET_ATON(str),address to number INET_NTOA(number),number to address MySQL内部的枚举类 ...

  2. MySQL优化/面试,看这一篇就够了

    原文链接:http://www.zhenganwen.top/articles/2018/12/25/1565048860202.html 作者:Anwen~链接:https://www.nowcod ...

  3. mysql 优化知识点

    附录: https://www.nowcoder.com/discuss/150059?type=0&order=0&pos=13&page=0 本文概要 概述 为什么要优化 ...

  4. 3万字总结,Mysql优化之精髓

    本文知识点较多,篇幅较长,请耐心学习 MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降. ...

  5. 【Mysql 优化 6】mysql优化的内容和思路

    根据最近做mysql优化,以及参照的官方文档的一些知识点,总结一下,如何下手去优化mysql 数据库.PS:更多可能是我个人的笔记总结记录,仅供参考 一.优化的内容 可以优化的内容,从范围的大小,可以 ...

  6. MYSQL优化之碎片整理

    MYSQL优化之碎片整理   在MySQL中,我们经常会使用VARCHAR.TEXT.BLOB等可变长度的文本数据类型.不过,当我们使用这些数据类型之后,我们就不得不做一些额外的工作--MySQL数据 ...

  7. MySQL优化整理

    一.SQL优化 1.show status查看各种sql的执行频率   SHOW STATUS 可以根据需要显示 session 级别的统计结果和 global级别的统计结果.   显示当前sessi ...

  8. 整理的网上的MySQL优化文章总结

    MySQL优化 Linux优化 IO优化 调整Linux默认的IO调度算法. IO调度器的总体目标是希望让磁头能够总是往一个方向移动,移动到底了再往反方向走,这恰恰就是现实生活中的电梯模型,所以IO调 ...

  9. MySQL优化概述

    一. MySQL优化要点 MySQL优化是一门复杂的综合性技术,主要包括: 1 表的设计合理化(符合 3NF,必要时允许数据冗余) 2.1 SQL语句优化(以查询为主) 2.2 适当添加索引(主键索引 ...

随机推荐

  1. MySQL乱码的几种原因

    MySQL之所以会乱码,无非是以下几种原因: 1.存进数据库之前就乱码 2.在存进数据库过程中乱码 3.存进数据库后乱码 想知道在哪里出现乱码很简单,在后台打印一下就知道了. 既然知道问题出在哪里,那 ...

  2. BZOJ 1109: [POI2007]堆积木Klo

    1109: [POI2007]堆积木Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 948  Solved: 341[Submit][Statu ...

  3. hadoop报错:WARN mapred.JobClient: Error reading task outputNo route to host

    解决方案: /etc/sysconfig/network/etc/hosts$hostname 这三处的主机名都要一样. 具体参考:http://blog.itpub.net/28254374/vie ...

  4. 【BZOJ-3052】糖果公园 树上带修莫队算法

    3052: [wc2013]糖果公园 Time Limit: 200 Sec  Memory Limit: 512 MBSubmit: 883  Solved: 419[Submit][Status] ...

  5. C语言之捕捉信号

    我们有时候需要在程序中做一些对于用户或内核发出的信号后的处理,如写回文件等善后处理的事情,或者直接忽略信号(当你按Ctrl+C时我压根不理你).下面是一段信号处理的代码(POSIX C): int c ...

  6. rfc2616 HTTP Protocl Analysis

    catalog . Introduction . Protocol Parameters . HTTP Message . Request . Response . HTTP Method.Conte ...

  7. fork子进程僵尸问题及解决方案

    额,原来用 c 写 cgi 的时候用过 fork .那时候 cgi 的生命很短,所以遇到的问题压根没出现过.这次也是更加深入的对 fork 机制进行了一下了解. 参考这里的文档:http://ju.o ...

  8. Handlers

    示例: - name: Configure webserver with nginx and tls hosts: webservers sudo: True vars: conf_file: /et ...

  9. AngularJs ngList、ngRepeat、ngModelOptions

    ngList 在文本输入的分隔的字符串和字符串数组间做转换,可以是一个固定的字符串分隔符(默认逗号)或正则表达式. 格式:ng-list=”value” value:表达式  通过这个值分隔字符串. ...

  10. linux学习笔记-dump命令的使用

    http://blog.chinaunix.net/uid-29797586-id-4458302.html