• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    简单了解添加mysql索引的3条原则

    一,索引的重要性

    索引用于快速找出在某个列中有一特定值的行。不使用索引,MySQL必须从第1条记录开始然后读完整个表直到找出相关的行。表越大,花费的时间越多。如果表中查询的列有一个索引,MySQL能快速到达一个位置去搜寻到数据文件的中间,没有必要看所有数据。注意如果你需要访问大部分行,顺序读取要快得多,因为此时我们避免磁盘搜索。

    假如你用新华字典来查找“张”这个汉字,不使用目录的话,你可能要从新华字典的第一页找到最后一页,可能要花二个小时。字典越厚呢,你花的时间就越多。现在你使用目录来查找“张”这个汉字,张的首字母是z,z开头的汉字从900多页开始,有了这条线索,你查找一个汉字可能只要一分钟,由此可见索引的重要性。但是索引建的是不是越多越好呢,当然不是,如果一本书的目录分成好几级的话,我想你也会晕的。

    二,准备工作

    //准备二张测试表 
    mysql> CREATE TABLE `test_t` ( 
    -> `id` int(11) NOT NULL auto_increment, 
    -> `num` int(11) NOT NULL default '0', 
    -> `d_num` varchar(30) NOT NULL default '0', 
    -> PRIMARY KEY (`id`) 
    -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 
    Query OK, 0 rows affected (0.05 sec) 
    mysql> CREATE TABLE `test_test` ( 
    -> `id` int(11) NOT NULL auto_increment, 
    -> `num` int(11) NOT NULL default '0', 
    -> PRIMARY KEY (`id`) 
    -> ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; 
    Query OK, 0 rows affected (0.05 sec) 
    //创建一个存储过程,为插数据方便 
    mysql> delimiter | 
    mysql> create procedure i_test(pa int(11),tab varchar(30)) 
    -> begin 
    -> declare max_num int(11) default 100000; 
    -> declare i int default 0; 
    -> declare rand_num int; 
    -> declare double_num char; 
    -> 
    -> if tab != 'test_test' then 
    -> select count(id) into max_num from test_t; 
    -> while i  pa do 
    -> if max_num  100000 then 
    -> select cast(rand()*100 as unsigned) into rand_num; 
    -> select concat(rand_num,rand_num) into double_num; 
    -> insert into test_t(num,d_num)values(rand_num,double_num); 
    -> end if; 
    -> set i = i +1; 
    -> end while; 
    -> else 
    -> select count(id) into max_num from test_test; 
    -> while i  pa do 
    -> if max_num  100000 then 
    -> select cast(rand()*100 as unsigned) into rand_num; 
    -> insert into test_test(num)values(rand_num); 
    -> end if; 
    -> set i = i +1; 
    -> end while; 
    -> end if; 
    -> end| 
    Query OK, 0 rows affected (0.00 sec) 
    mysql> delimiter ; 
    mysql> show variables like "%pro%"; //查看一下,记录执行的profiling是不是开启动了,默认是不开启的 
    +---------------------------+-------+ 
    | Variable_name | Value | 
    +---------------------------+-------+ 
    | profiling | OFF | 
    | profiling_history_size | 15 | 
    | protocol_version | 10 | 
    | slave_compressed_protocol | OFF | 
    +---------------------------+-------+ 
    4 rows in set (0.00 sec) 
    mysql> set profiling=1; //开启后,是为了对比加了索引后的执行时间 
    Query OK, 0 rows affected (0.00 sec) 

    三,实例

    1,单表数据太少,索引反而会影响速度

    mysql> call i_test(10,'test_t'); //向test_t表插入10条件 
    Query OK, 1 row affected (0.02 sec) 
    mysql> select num from test_t where num!=0; 
    mysql> explain select num from test_t where num!=0\G; 
    *************************** 1. row *************************** 
    id: 1 
    select_type: SIMPLE 
    table: test_t 
    type: ALL 
    possible_keys: NULL 
    key: NULL 
    key_len: NULL 
    ref: NULL 
    rows: 10 
    Extra: Using where 
    1 row in set (0.00 sec) 
    ERROR: 
    No query specified 
    mysql> create index num_2 on test_t (num); 
    Query OK, 10 rows affected (0.19 sec) 
    Records: 10 Duplicates: 0 Warnings: 0 
    mysql> select num from test_t where num!=0; 
    mysql> explain select num from test_t where num!=0\G; 
    *************************** 1. row *************************** 
    id: 1 
    select_type: SIMPLE 
    table: test_t 
    type: index 
    possible_keys: num_2 
    key: num_2 
    key_len: 4 
    ref: NULL 
    rows: 10 
    Extra: Using where; Using index 
    1 row in set (0.00 sec) 
    ERROR: 
    No query specified 
    mysql> show profiles; 
    +----------+------------+---------------------------------------------+ 
    | Query_ID | Duration | Query | 
    +----------+------------+---------------------------------------------+ 
    | 1 | 0.00286325 | call i_test(10,'test_t') | //插入十条数据 
    | 2 | 0.00026350 | select num from test_t where num!=0 | 
    | 3 | 0.00022250 | explain select num from test_t where num!=0 | 
    | 4 | 0.18385400 | create index num_2 on test_t (num) | //创建索引 
    | 5 | 0.00127525 | select num from test_t where num!=0 | //使用索引后,差不多是没有使用索引的0.2倍 
    | 6 | 0.00024375 | explain select num from test_t where num!=0 | 
    +----------+------------+---------------------------------------------+ 
    6 rows in set (0.00 sec) 

    解释:

    前段时间写过一篇博文mysql distinct和group by谁更好,里面有朋友留言,说测试结果根我当时做的测试结果不一样,当时我打比方解释了一下,今天有时间,以例子的形势,更直观的表达出索引的工作原理。

    2,where后的条件,order by ,group by 等这样过滤时,后面的字段最好加上索引。根据实际情况,选择PRIMARY KEY、UNIQUE、INDEX等索引,但是不是越多越好,要适度。

    3,联合查询,子查询等多表操作时关连字段要加索引

    mysql> call i_test(10,'test_test'); //向test_test表插入10条数据 
    Query OK, 1 row affected (0.02 sec) 
    mysql> explain select a.num as num1,b.num as num2 from test_t as a left join tes 
    t_test as b on a.num=b.num\G; 
    *************************** 1. row *************************** 
    id: 1 
    select_type: SIMPLE 
    table: a 
    type: index 
    possible_keys: NULL 
    key: num_2 
    key_len: 4 
    ref: NULL 
    rows: 10 
    Extra: Using index 
    *************************** 2. row *************************** 
    id: 1 
    select_type: SIMPLE 
    table: b 
    type: ref 
    possible_keys: num_1 
    key: num_1 
    key_len: 4 
    ref: bak_test.a.num //bak_test是数据库名,a.num是test_t的一个字段 
    rows: 1080 
    Extra: Using index 
    2 rows in set (0.01 sec) 
    ERROR: 
    No query specified 

    数据量特别大的时候,最好不要用联合查询,即使你做了索引。

    上面只是个人的一点小结,抛砖引玉一下。

    以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    您可能感兴趣的文章:
    • Mysql如何适当的添加索引介绍
    • MySQL常用的建表、添加字段、修改字段、添加索引SQL语句写法总结
    • mysql为字段添加和删除唯一性索引(unique) 的方法
    • MySQL修改表一次添加多个列(字段)和索引的方法
    • mysql占用CPU过高的解决办法(添加索引)
    • mysql 添加索引 mysql 如何创建索引
    上一篇:MySQL分表和分区的具体实现方法
    下一篇:mysql如何在已有数据库上统一字符集
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    简单了解添加mysql索引的3条原则 简单,了解,添加,mysql,索引,