注意:Index(Name,Age)表示在Name,Age两列上建立联合索引
由于索引对数据库的查询性能有着至关重要的影响,下面是我的一些总结和体会:
一个查询一次只能使用一个索引:select name from user where name=’plantegg’ and age>35 , 如果Index(name); Index(age)的话,MySQL查询优化器会自动选择一个索引来使用;
MySQL选择哪个索引,可以这样来看:mysql> show index from photo;
+——-+————+————————+————–+—————+———–+————-+———-+——–+——+————+———+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+——-+————+————————+————–+—————+———–+————-+———-+——–+——+————+———+
| photo | 0 | PRIMARY | 1 | photo_id | A | 237871 | NULL | NULL | | BTREE | |
| photo | 1 | index_random | 1 | random | A | 237871 | NULL | NULL | YES | BTREE | |
| photo | 1 | FK_photo_profile_id | 1 | profile_id | A | 237871 | NULL | NULL | | BTREE | |
| photo | 1 | FK_photo_temp_photo_id | 1 | temp_photo_id | A | 237871 | NULL | NULL | YES | BTREE | |
| photo | 1 | FK_photo_album_id | 1 | album_id | A | 237871 | NULL | NULL | YES | BTREE | |
+——-+————+————————+————–+—————+———–+————-+———-+——–+——+————+———+
关于建立索引的几个准则:
1、合理的建立索引能够加速数据读取效率,不合理的建立索引反而会拖慢数据库的响应速度。
2、索引越多,更新数据的速度越慢。
3、尽量在采用MyIsam作为引擎的时候使用索引(因为MySQL以BTree存储索引),而不是InnoDB。但MyISAM不支持Transcation。
4、当你的程序和数据库结构/SQL语句已经优化到无法优化的程度,而程序瓶颈并不能顺利解决,那就是应该考虑使用诸如memcached这样的分布式缓存系统的时候了。
5、习惯和强迫自己用EXPLAIN来分析你SQL语句的性能。
1.SQL需求,统计当天的数据量。
SQL> SELECT count(*) FROM test_union WHERE win_type=1 AND gmt_create >= trunc(sysdate,'dd') and gmt_create <= trunc(sysdate,'dd')+1;
COUNT(*)
----------
20063
1 row selected.
2.查看其索引,以gmt_create开头。
sql>create index idx_union on test_union (gmt_create,win_type) tablespace tbs_index compute statistics;
3.查看awr报表的性能,逻辑读很高,达到9700个。
Buffer Gets Executions Gets per Exec %Total Time Time (s) Hash Value
--------------- ---------- -------------- ------ -------- --------- ------
205,157,987 21,236 9,660.9 34.5 6733.21 7568.58 1532799124
Module: java@app12345 (TNS V1-V3)
SELECT count(*) FROM test_union WHERE win_type=1 AND gmt_create >= trunc(sysdate,'dd') and gmt_create <= trunc(sysdate,'dd')+1
因为是只通过索引扫描,当看到返回结果集在2万左右,我们很容易估算出这个sql需要的逻辑读,(gmt_date字段7个字节+win_type字段1个字节+rowid+…)*2万,小于100个,现在很明显是偏高的。
所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。
一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。
对于CHAR和VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。在CREATE TABLE语句中索引列前缀的语法看起来像这样:
KEY index_name (col_name(length))
下面的例子为name列的头10个字符创建一个索引:
CREATE TABLE test (
name CHAR(200) NOT NULL,
KEY index_name (name(10)));
对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。