查看表相关命令

- 查看表结构   desc 表名- 查看生成表的SQL   show create table 表名- 查看索引   show index from  表名

使用索引和不使用索引

由于索引是专门用于加速搜索而生,所以加上索引之后,查询效率会快到飞起来。

# 有索引
mysql> select * from tb1 where name = 'zhangqiye';
+-----+-------------+---------------------+----------------------------------+---------------------+
| nid | name        | email               | radom                            | ctime               |
+-----+-------------+---------------------+----------------------------------+---------------------+
| 889 | zhangqiye | zhangqiye@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
+-----+-------------+---------------------+----------------------------------+---------------------+
1 row in set (0.00 sec)

 
# 无索引
mysql> select * from tb1 where email = 'zhangqiye@live.com';
+-----+-------------+---------------------+----------------------------------+---------------------+
| nid | name        | email               | radom                            | ctime               |
+-----+-------------+---------------------+----------------------------------+---------------------+
| 889 | zhangqiye | wupeiqi888@live.com | 5312269e76a16a90b8a8301d5314204b | 2016-08-03 09:33:35 |
+-----+-------------+---------------------+----------------------------------+---------------------+
1 row in set (1.23 sec) 

正确使用索引

数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。

即使建立索引,索引也不会生效的情况:

- like '%xx'   select * from tb1 where name like '%cn';- 使用函数   select * from tb1 where reverse(name) = 'zhangqiye';- or   select * from tb1 where nid = 1 or email = 'seven@live.com';   特别的:当or条件中有未建立索引的列才失效,以下会走索引           select * from tb1 where nid = 1 or name = 'seven';           select * from tb1 where nid = 1 or email = 'seven@live.com' and name = 'zhangqiye'- 类型不一致   如果列是字符串类型,传入条件是必须用引号引起来,不然...   select * from tb1 where name = 999;- !=   select * from tb1 where name != 'zhangqiye'   特别的:如果是主键,则还是会走索引       select * from tb1 where nid != 123- >   select * from tb1 where name > 'zhangqiye'   特别的:如果是主键或索引是整数类型,则还是会走索引       select * from tb1 where nid > 123       select * from tb1 where num > 123- order by   select email from tb1 order by name desc;   当根据索引排序时候,选择的映射如果不是索引,则不走索引   特别的:如果对主键排序,则还是走索引:       select * from tb1 order by nid desc;

- 组合索引最左前缀   如果组合索引为:(name,email)   name and email       -- 使用索引   name                 -- 使用索引   email                -- 不使用索引

其他注意事项

- 避免使用select *- count(1)或count(列) 代替 count(*)- 创建表时尽量时 char 代替 varchar- 表的字段顺序固定长度的字段优先- 组合索引代替多个单列索引(经常使用多个条件查询时)- 尽量使用短索引- 使用连接(JOIN)来代替子查询(Sub-Queries)- 连表时注意条件类型需一致- 索引散列值(重复少)不适合建索引,例:性别不适合

limit分页

无论是否有索引,limit分页是一个值得关注的问题

mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。

直接用limit start, count分页语句

select * from product limit start, count
当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下:

select * from product limit 10, 20   0.016秒select * from product limit 100, 20   0.016秒select * from product limit 1000, 20   0.047秒select * from product limit 10000, 20   0.094秒

我们已经看出随着起始记录的增加,时间也随着增大, 这说明分页语句limit跟起始页码是有很大关系的,那么我们把起始记录改为40w看下(也就是记录的一般左右)      select * from product limit 400000, 20   3.229秒

再看我们取最后一页记录的时间
select * from product limit 866613, 20   37.44秒

难怪搜索引擎抓取我们页面的时候经常会报超时,像这种分页最大的页码页显然这种时
间是无法忍受的。

从中我们也能总结出两件事情:
1)limit语句的查询时间与起始记录的位置成正比
2)mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。

对limit分页问题的性能优化方法

利用表的覆盖索引来加速分页查询
我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。

因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。

在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何:

这次我们之间查询最后一页的数据(利用覆盖索引,只包含id列),如下:
select id from product limit 866613, 20 0.2秒
相对于查询了所有列的37.44秒,提升了大概100多倍的速度

那么如果我们也要查询所有列,有两种方法,一种是id>=的形式,另一种就是利用join,看下实际情况:

SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
查询时间为0.2秒,简直是一个质的飞跃啊,哈哈

另一种写法SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id查询时间也很短,赞!

其实两者用的都是一个原理嘛,所以效果也差不多

执行计划

explain + 查询SQL - 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化

如:mysql> explain select * from (select nid,name from tb1 where nid < 10) as B;
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
| id | select_type | table      | type  | possible_keys | key     | key_len | ref  | rows | Extra       |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+
|  1 | PRIMARY     | <derived2> | ALL   | NULL          | NULL    | NULL    | NULL |    9 | NULL        |
|  2 | DERIVED     | tb1        | range | PRIMARY       | PRIMARY | 8       | NULL |    9 | Using where |
+----+-------------+------------+-------+---------------+---------+---------+------+------+-------------+

结果字段说明

id:查询顺序标识

select_type

查询类型

SIMPLE                 简单查询

PRIMARY              最外层查询

SUBQUERY          映射为子查询

DERIVED              子查询

UNION                   联合

UNION RESULT    使用联合的结果

table:正在访问的表名

type

查询时的访问方式,性能:all < index < range < index_merge < ref_or_null < ref < eq_ref < system/const

ALL (必须进行优化)

全表扫描,对于数据表从头到尾找一遍

select * from tb1;

特别的:如果有limit限制,则找到之后就不在继续向下扫描

select * from tb1 where email = 'seven@live.com'

select * from tb1 where email = 'seven@live.com' limit 1;

虽然上述两个语句都会进行全表扫描,第二句使用了limit,则找到一个后就不再继续扫描。

INDEX

全索引扫描,对索引从头到尾找一遍

select nid from tb1;

RANGE

对索引列进行范围查找

select *  from tb1 where name < 'zhagsan';

between and

in

>   >=  <   <=  操作

注意:!= 和 > 符号

INDEX_MERGE

合并索引,使用多个单列索引搜索

select *  from tb1 where name = zhangsan' or nid in (11,22,33);

REF

根据索引查找一个或多个值

select *  from tb1 where name = 'seven';

EQ_REF

连接时使用primary key 或 unique类型

select tb2.nid,tb1.name from tb2 left join tb1 on tb2.nid = tb1.nid;

CONST

常量

表最多有一个匹配行,因为仅有一行,在这行的列值可被优化器剩余部分认为是常数,const表很快,因为它们只读取一次。

select nid from tb1 where nid = 2 ;

SYSTEM

系统

表仅有一行(=系统表)。这是const联接类型的一个特例。

select * from (select nid from tb1 where nid = 1) as A;

possible_keys:可能使用的索引

key :真实使用的

key_len:MySQL中使用索引字节长度

rows

mysql估计为了找到所需的行而要读取的行数 ------ 只是预估值

慢日志查询

MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。long_query_time的默认值为10,意思是运行10S以上的语句。默认情况下,Mysql数据库并不启动慢查询日志,需要我们手动来设置这个参数,当然,如果不是调优需要的话,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件,也支持将日志记录写入数据库表。

MySQL 慢查询的相关参数解释

slow_query_log    :是否开启慢查询日志,1表示开启,0表示关闭。log-slow-queries  :旧版(5.6以下版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.logslow-query-log-file:新版(5.6及以上版本)MySQL数据库慢查询日志存储路径。可以不设置该参数,系统则会默认给一个缺省的文件host_name-slow.loglong_query_time :慢查询阈值,当查询时间多于设定的阈值时,记录日志。log_queries_not_using_indexes:未使用索引的查询也被记录到慢查询日志中(可选项)。log_output:日志存储方式。log_output='FILE'表示将日志存入文件,默认值是'FILE'。log_output='TABLE'表示将日志存入数据库,这样日志信息就会被写入到mysql.slow_log表中。MySQL数据<br>库支持同时两种日志存储方式,配置的时候以逗号隔开即可,如:log_output='FILE,TABLE'。日志记录到系统的专用日志表中,要比记录到文件耗费更多的系统资源,因此对于需要启用慢查询日志,又需<br>要能够获得更高的系统性能,那么建议优先记录到文件。

开启慢查询

找到 MySQL 的配置文件 ,my.cnf (Windows 为 my.ini ),在 [mysqld]下增加下面几行:

slow_query_log = 1                          long_query_time = 2                           slow_query_log_file = /usr/slow.log       log_queries_not_using_indexes = 1

重新启动MySQL服务

MySQL 配置文件的位置

Windows:Windows 的配置文件为 my.ini,一般在 MySQL 的安装目录下或者 c:\Windows 下。

Linux:Linux 的配置文件为 my.cnf ,一般在 /etc 下。


识别图中二维码,领取python全套视频

转载于:https://www.cnblogs.com/IT-Scavenger/p/9192506.html

正确使用索引(sql优化),limit分页优化,执行计划,慢日志查询相关推荐

  1. 数据库面试题【十八、优化关联查询优化子查询优化LIMIT分页优化UNION查询优化WHERE子句】

    优化关联查询: 确定ON或者USING子句中是否有索引. 确保GROUP BY和ORDER BY只有一个表中的列,这样MySQL才有可能使用索引. 优化子查询: 用关联查询替代 优化GROUP BY和 ...

  2. mysql limit 越大越慢_mysql 优化之14:php mysql limit 分页优化,页面值越大查询越慢...

    php mysql limit 分页优化,页面越大查询越慢 一.测试前言 当前测试表:nodes_hierarchy目前数据量为20多万 程序分页中我们经常使用的核心sql语句select * fro ...

  3. 【MySQL性能优化系列】百万数据limit分页优化

    背景 众所周知,在使用limit分页过程中,随着前端传过来的PageSize越来越大,查询速度会越来越慢.那有什么优化的办法呢? 本文将通过百万数据表进行演示和优化, 欲知详情,请看下文分解. lim ...

  4. MySQL中的limit分页优化

    MySQL中的limit分页优化 MySQL的limit优化 mysql的分页比较简单,只需要limit offset,length就可以获取数据了,但是当offset和length比较大的时候,my ...

  5. mysql limit 分页 优化_MYSQL分页limit速度太慢优化方法

    在mysql中limit可以实现快速分页,但是如果数据到了几百万时我们的limit必须优化才能有效的合理的实现分页了,否则可能卡死你的服务器哦. 当一个表数据有几百万的数据的时候成了问题! 如 * f ...

  6. php超大树形分页,PHP+MySql千万级数据limit分页优化方案

    PHP+MySql千万级数据limit分页优化方案 1年前 阅读 2750 评论 0 喜欢 0 ### 原因 徒弟突然有个需求,就是他发现limit分页,页数越大之后,mysql的消耗越大,查询时间越 ...

  7. SQL Server 执行计划利用统计信息对数据行的预估原理二(为什么复合索引列顺序会影响到执行计划对数据行的预估)...

    本文出处:http://www.cnblogs.com/wy123/p/6008477.html 关于统计信息对数据行数做预估,之前写过对非相关列(单独或者单独的索引列)进行预估时候的算法,参考这里. ...

  8. sql server运算符_SQL Server执行计划中SELECT运算符的主要概念

    sql server运算符 One of the main responsibilities of a database administrator is query tuning and troub ...

  9. [sqlserver脚本]查看指定SQL语句生成了哪些执行计划

    参考SQL技术内幕写了一段脚本,可以通过这段脚本查看执行指定SQL语句后,系统生成了哪些执行计划.使用时注意以下几点: 修改use MyTest,换成自己的数据库名字. 将 exec sp_page_ ...

最新文章

  1. Android事件机制
  2. ACK正式支持对基于Alibaba Cloud Linux操作系统的集群进行等保加固
  3. windows bat 批处理 !vm 合并快播文件
  4. u-boot,linux,文件系统移植笔记1
  5. WPF设计の自定义窗体
  6. explain是mysql的关键字吗_Mysql Explain 关键字
  7. [MTK][FAQ20888] 开关机、重启时间优化
  8. UC浏览器去广告、联网、升级(支持新版8.1)
  9. springboot 整合 ftps
  10. elasticsearch 7.4 常用查询/搜索方式
  11. POP3协议命令原始码及工作原理
  12. 【通过】华为OD机试真题59:叠积木
  13. 如何从用户旅程图中挖掘差异化需求?
  14. css实现烟雾效果(css制作汽车尾气排放效果)
  15. 线性代数学习笔记——第五十七讲——特征子空间
  16. 计算机游戏教学法的创新之处,游戏教学法在小学英语课堂论文开题报告的创新点...
  17. win2003 iis 设置301转向
  18. 脸上用激光手术点完痦子之后出现疤痕增生怎么处理比较好
  19. 2017AI最成功案例
  20. Git + Github初入门

热门文章

  1. Linux(Ubuntu 16) 下Java开发环境的配置(一)------JDK的配置
  2. Linux文件大小排序
  3. Oracle生成指定表的列名,并前后添加select from
  4. 收回误删并清除了回收站的文档
  5. 批量修改MSSQL架构名称
  6. Internet Explorer 8 Beta 2十大看点
  7. [导入]Don's Loose
  8. C# ToString()方法
  9. Java Lambda表达式forEach无法跳出循环的解决思路
  10. 线性回归——lasso回归和岭回归(ridge regression)