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_insert1\G
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;

 

posted @ 2017-09-18 23:51  liqianlong  阅读(1013)  评论(0编辑  收藏  举报