zoukankan      html  css  js  c++  java
  • python开发mysql:索引

    一,索引管理

     1 索引分类:
     2 普通索引INDEX:加速查找
     3 
     4 唯一索引:
     5     -主键索引PRIMARY KEY:加速查找+约束(不为空、不能重复)
     6     -唯一索引UNIQUE:加速查找+约束(不能重复)
     7 
     8 联合索引:
     9     -PRIMARY KEY(id,name):联合主键索引
    10     -UNIQUE(id,name):联合唯一索引
    11     -INDEX(id,name):联合普通索引
    12 
    13 1 创建索引
    14     - 在创建表时就创建
    15         create table s1(
    16         id int,
    17         name char(6),
    18         age int,
    19         email varchar(30),
    20         index(id)
    21         );
    22     - 在创建表后创建
    23         create index name on s1(name);#添加普通索引
    24         create unique index age on s1(age);#添加唯一索引
    25         alter table s1 add primary key(id);#添加主键索引
    26         create index name on s1(id,name);#添加联合普通索引
    27 ** 在创表的时候创建只能写在后面单写,因为他不是起约束的作用
    28 
    29 2 删除索引
    30     drop index id on s1;
    31     drop index name on s1;
    32     alter table s1 add primary key(id,name);联合主键索引
    33     alter table s1 drop primary key;#删除主键索引
    34 
    35 3 正确使用索引
    36     select sql_no_cache * from s1 where email='xxx'; #命中索引,速度很快
    37     select sql_no_cache * from s1 where email like '%old%'; #无法使用索引,速度依然很慢
    38 
    39 
    40 
    41 
    42 4 存储过程,主要用来生成多数据,然后按照普通查询和索引查询对比一下查询的时间
    43 #1. 准备表
    44 create table s1(
    45 id int,
    46 name varchar(20),
    47 gender char(6),
    48 email varchar(50)
    49 );
    50 
    51 #2. 创建存储过程,实现批量插入记录
    52 delimiter $$ #声明存储过程的结束符号为$$
    53 create procedure auto_insert1()
    54 BEGIN
    55     declare i int default 1;
    56     while(i<3000000)do
    57         insert into s1 values(i,concat('egon',i),'male',concat('egon',i,'@oldboy'));
    58         set i=i+1;
    59     end while;
    60 END$$ #$$结束
    61 delimiter ; #重新声明分号为结束符号
    62 
    63 #3. 查看存储过程
    64 show create procedure auto_insert1G
    65 
    66 #4. 调用存储过程
    67 call auto_insert1();
    68 
    69 #5. 删除存储过程
    70 drop procedure auto_insert1;
    71 
    72 #6. 显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
    73 show procedure status

    二,索引使用

      1 ** 索引必须是一个明确的值才能体现其查询速度,例如where id=30521,如果是范围操作(大于,小于,between),就是还是需要循环判断,索引就不起作用
      2 
      3 1 加索引提速
      4 无索引
      5 mysql> select count(*) from s1 where id=1000;
      6 +----------+
      7 | count(*) |
      8 +----------+
      9 |        1 |
     10 +----------+
     11 1 row in set (0.12 sec)
     12 
     13 mysql> select count(*) from s1 where id>1000;
     14 +----------+
     15 | count(*) |
     16 +----------+
     17 |   298999 |
     18 +----------+
     19 1 row in set (0.12 sec)
     20 
     21 有索引
     22 mysql> create index a on s1(id)
     23     -> ;
     24 Query OK, 0 rows affected (3.21 sec)
     25 Records: 0  Duplicates: 0  Warnings: 0
     26 
     27 mysql> select count(*) from s1 where id=1000;
     28 +----------+
     29 | count(*) |
     30 +----------+
     31 |        1 |
     32 +----------+
     33 1 row in set (0.00 sec)
     34 
     35 mysql> select count(*) from s1 where id>1000;
     36 +----------+
     37 | count(*) |
     38 +----------+
     39 |   298999 |
     40 +----------+
     41 1 row in set (0.12 sec)
     42 ** 索引必须是一个能查询明确的值才能体现其查询速度,
     43 
     44 
     45 2 范围
     46 #范围小的话,索引有用
     47 mysql> select count(*) from s1 where id>1000 and id < 2000;
     48 +----------+
     49 | count(*) |
     50 +----------+
     51 |      999 |
     52 +----------+
     53 1 row in set (0.00 sec)
     54 
     55 #范围大的话,索引没用
     56 mysql> select count(*) from s1 where id>1000 and id < 300000;
     57 +----------+
     58 | count(*) |
     59 +----------+
     60 |   298999 |
     61 +----------+
     62 1 row in set (0.13 sec)
     63 ** 范围小可以体现索引的作用,大范围还是要逐个循环
     64 
     65 
     66 3 区分度低的字段不能加索引
     67 有索引
     68 mysql> create index b on s1(name)
     69     -> ;
     70 Query OK, 0 rows affected (3.21 sec)
     71 Records: 0  Duplicates: 0  Warnings: 0
     72 
     73 mysql> select count(*) from s1 where name='xxx';
     74 +----------+
     75 | count(*) |
     76 +----------+
     77 |        0 |
     78 +----------+
     79 1 row in set (0.00 sec)
     80 
     81 mysql> select count(*) from s1 where name='egon';
     82 +----------+
     83 | count(*) |
     84 +----------+
     85 |   299999 |
     86 +----------+
     87 1 row in set (0.19 sec)
     88 ** 表内name都是egon这个值,所以有30万个egon,都是要一行一行去匹配
     89 
     90 mysql> select count(*) from s1 where name='egon' and age=123123123123123;
     91 +----------+
     92 | count(*) |
     93 +----------+
     94 |        0 |
     95 +----------+
     96 1 row in set (0.45 sec)
     97 
     98 mysql> select count(*) from s1 where name='dfsdfdsfdfdsfdsfdsf' and age=123123123123123;
     99 +----------+
    100 | count(*) |
    101 +----------+
    102 |        0 |
    103 +----------+
    104 1 row in set (0.00 sec)
    105 ** 同上面结论
    106 
    107 mysql> create index c on s1(age);
    108 Query OK, 0 rows affected (3.03 sec)
    109 Records: 0  Duplicates: 0  Warnings: 0
    110 
    111 mysql> select count(*) from s1 where name='egon' and age=123123123123123;
    112 +----------+
    113 | count(*) |
    114 +----------+
    115 |        0 |
    116 +----------+
    117 1 row in set (0.00 sec)
    118 
    119 mysql> select count(*) from s1 where name='egon' and age=10;
    120 +----------+
    121 | count(*) |
    122 +----------+
    123 |   299999 |
    124 +----------+
    125 1 row in set (0.35 sec)
    126 ** 之所以加速,因为and是同时,也就是age右边可以瞬间定位,再比对nmae
    127 
    128 mysql> select count(*) from s1 where name='egon' and age=10;
    129 +----------+
    130 | count(*) |
    131 +----------+
    132 |      999 |
    133 +----------+
    134 1 row in set (0.00 sec)
    135 age=10 区分度高
    136 
    137 mysql> select count(*) from s1 where name='egon' and agw>50;
    138 +----------+
    139 | count(*) |
    140 +----------+
    141 |        0 |
    142 +----------+
    143 1 row in set (0.47 sec)
    144 
    145 mysql> select count(*) from s1 where name='egon' and age>100 and age < 600;
    146 +----------+
    147 | count(*) |
    148 +----------+
    149 |      999 |
    150 +----------+
    151 1 row in set (0.00 sec)
    152 ** 区分度高原则,范围原则小,差异就小
    153 
    154 
    155 4 mysql> create index d on s1(email);
    156 Query OK, 0 rows affected (4.83 sec)
    157 Records: 0  Duplicates: 0  Warnings: 0
    158 
    159 mysql> select count(*) from s1 where name='egon' and age=10 and id>3000 and email='xxxx';
    160 +----------+
    161 | count(*) |
    162 +----------+
    163 |        0 |
    164 +----------+
    165 1 row in set (0.00 sec)
    166 
    167 mysql> drop index a on s1;
    168 Query OK, 0 rows affected (0.10 sec)
    169 Records: 0  Duplicates: 0  Warnings: 0
    170 
    171 mysql> drop index b on s1;
    172 Query OK, 0 rows affected (0.09 sec)
    173 Records: 0  Duplicates: 0  Warnings: 0
    174 
    175 mysql> drop index c on s1;
    176 Query OK, 0 rows affected (0.09 sec)
    177 Records: 0  Duplicates: 0  Warnings: 0
    178 
    179 mysql> desc s1;
    180 +-------+-------------+------+-----+---------+-------+
    181 | Field | Type        | Null | Key | Default | Extra |
    182 +-------+-------------+------+-----+---------+-------+
    183 | id    | int(11)     | NO   |     | NULL    |       |
    184 | name  | char(20)    | YES  |     | NULL    |       |
    185 | age   | int(11)     | YES  |     | NULL    |       |
    186 | email | varchar(30) | YES  | MUL | NULL    |       |
    187 +-------+-------------+------+-----+---------+-------+
    188 4 rows in set (0.00 sec)
    189 
    190 mysql> select count(*) from s1 where name='egon' and age=10 and id>3000 and email='xxxx';
    191 +----------+
    192 | count(*) |
    193 +----------+
    194 |        0 |
    195 +----------+
    196 1 row in set (0.00 sec)
    197 ** 区分度高原则,范围原则小,差异就小,email最高
    198 
    199 
    200 5 增加联合索引,关于范围查询的字段要放到后面
    201  select count(*) from s1 where name='egon' and age=10 and id>3000 and email='xxxx';
    202  index(name,email,age,id)
    203 
    204  select count(*) from s1 where name='egon' and age> 10 and id=3000 and email='xxxx';
    205 index(name,email,id,age)
    206 
    207  select count(*) from s1 where name like 'egon' and age= 10 and id=3000 and email='xxxx';
    208 index(email,id,age,name)
    209 
    210 mysql> desc s1;
    211 +-------+-------------+------+-----+---------+-------+
    212 | Field | Type        | Null | Key | Default | Extra |
    213 +-------+-------------+------+-----+---------+-------+
    214 | id    | int(11)     | NO   |     | NULL    |       |
    215 | name  | char(20)    | YES  |     | NULL    |       |
    216 | age   | int(11)     | YES  |     | NULL    |       |
    217 | email | varchar(30) | YES  |     | NULL    |       |
    218 +-------+-------------+------+-----+---------+-------+
    219 4 rows in set (0.00 sec)
    220 
    221 mysql> create index xxx on s1(age,email,name,id);
    222 Query OK, 0 rows affected (6.89 sec)
    223 Records: 0  Duplicates: 0  Warnings: 0
    224 
    225 mysql> select count(*) from s1 where name='egon' and age=10 and id>3000 and email='xxxx';
    226 +----------+
    227 | count(*) |
    228 +----------+
    229 |        0 |
    230 +----------+
    231 1 row in set (0.00 sec)
    232 
    233 6. 联合索引,最左前缀匹配,多用于and
    234 index(id,age,email,name)
    235 #条件中一定要出现id
    236 id
    237 id age
    238 id email
    239 id name
    240 
    241 email #不行,最左边匹配
    242 mysql> select count(*) from s1 where id=3000;
    243 +----------+
    244 | count(*) |
    245 +----------+
    246 |        1 |
    247 +----------+
    248 1 row in set (0.11 sec)
    249 
    250 mysql> create index xxx on s1(id,name,age,email);
    251 Query OK, 0 rows affected (6.44 sec)
    252 Records: 0  Duplicates: 0  Warnings: 0
    253 
    254 mysql>  select count(*) from s1 where id=3000;
    255 +----------+
    256 | count(*) |
    257 +----------+
    258 |        1 |
    259 +----------+
    260 1 row in set (0.00 sec)
    261 
    262 mysql>  select count(*) from s1 where name='egon';
    263 +----------+
    264 | count(*) |
    265 +----------+
    266 |   299999 |
    267 +----------+
    268 1 row in set (0.16 sec)
    269 
    270 mysql>  select count(*) from s1 where email='egon3333@oldboy.com';
    271 +----------+
    272 | count(*) |
    273 +----------+
    274 |        1 |
    275 +----------+
    276 1 row in set (0.15 sec)
    277 
    278 mysql>  select count(*) from s1 where id=1000 and email='egon3333@oldboy.com';
    279 +----------+
    280 | count(*) |
    281 +----------+
    282 |        0 |
    283 +----------+
    284 1 row in set (0.00 sec)
    285 
    286 mysql>  select count(*) from s1 where email='egon3333@oldboy.com' and id=3000;
    287 +----------+
    288 | count(*) |
    289 +----------+
    290 |        0 |
    291 +----------+
    292 1 row in set (0.00 sec)
    293 ** 最左匹配,如果没有Id就会有时间得到结果
    294 
    295 
    296 6.索引列不能参与计算,参与计算,所以就没有意义,保持列“干净”
    297 mysql>  select count(*) from s1 where id*3;
    298 +----------+
    299 | count(*) |
    300 +----------+
    301 |   299999 |
    302 +----------+
    303 1 row in set (0.16 sec)
    304 
    305 ** 用不上索引
    306 like 函数 or 类型不一致 != > < order by
    307 
    308 类型不一致
    309 mysql> select count(*) from s1 where id='3000';
    310 +----------+
    311 | count(*) |
    312 +----------+
    313 |        1 |
    314 +----------+
    315 1 row in set
    316 
    317 mysql>  select count(*) from s1 where id=3000;
    318 +----------+
    319 | count(*) |
    320 +----------+(0.11 sec)
    321 |        1 |
    322 +----------+
    323 1 row in set (0.00 sec)
    324 
    325 order by 模糊
    326 select id from s1 order by id;
    327 
    328 or 只有id是索引,必须是左右2边单独有索引才能提速,叫做索引合并
    329 mysql>  select count(*) from s1 where id=1000 or email='xxx';
    330 +----------+
    331 | count(*) |
    332 +----------+
    333 |        0 |
    334 +----------+
    335 1 row in set (0.13 sec)
    336 
    337 
    338 慢查询
    339 在Mysqld下面配置
    340 slow-query-log=1341 slow-query-log-file=slow.log 存放位置
    342 long_query_time=3 超时限制3毫秒就会被记录
    343 
    344 在cmd里面
    345 set global slow-query-log=ON;
    346 show variables like '%query%';
    347 set session long_query_time=3;
  • 相关阅读:
    微擎开发笔记
    Array对象的方法实现(1)----Array.prototype.push和Array.prototype.concat(实现常规参数的功能)
    ThinkCMF 5 基础门户CMS框架的模板widget标签实现
    [转]mysql为什么默认有那么多root用户,还有用户名为空的用户?
    PHP 5.4特性 trait
    道破人性
    c#使用easyhook库进行API钩取
    黑马eesy_15 Vue:04.综合案例(前端Vue实现)
    黑马eesy_15 Vue:04.Vue案例(ssm环境搭建)
    黑马eesy_15 Vue:03.生命周期与ajax异步请求
  • 原文地址:https://www.cnblogs.com/jokerbj/p/7546009.html
Copyright © 2011-2022 走看看