3、拆分表
比如一张70G的大表,数据记录数达到上亿条,这时在对大表操作就会比对小表操作消耗性能大,所以通过取模的形式
insert into table_new_0 select * from table_old where mod(user_id,100)=0;
insert into table_new_1 select * from table_old where mod(user_id,100)=1;
insert into table_new_2 select * from table_old where mod(user_id,100)=2;
……
insert into table_new_99 select * from table_old where mod(user_id,100)=99;
搜狐、人人网也采用了此类方法。
例1、order by优化
mysql> desc student;
+-------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | varchar(6) | YES | | NULL | |
| class | int(11) | YES | MUL | NULL | |
| score | int(11) | YES | | NULL | |
+-------+------------+------+-----+---------+-------+
4 rows in set (0.12 sec)
student表学生id为主键,班级ID是索引。
mysql> explain select * from student where class = 1 order by score DESC;
+----+-------------+---------+------+---------------+-------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+-------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | student | ref | class | class | 5 | const | 2 | Using where; Using filesort |
+----+-------------+---------+------+---------------+-------+---------+-------+------+-----------------------------+
1 row in set (0.03 sec)
mysql> show index from student;
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| student | 0 | PRIMARY | 1 | id | A | 8 | NULL | NULL | | BTREE | | |
| student | 1 | class | 1 | class | A | 8 | NULL | NULL | YES | BTREE | | |
| student | 1 | class | 2 | score | A | 8 | NULL | NULL | YES | BTREE | | |
+---------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
3 rows in set (0.03 sec)
mysql> explain select * from student where class = 1 order by score DESC;
+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+
| 1 | SIMPLE | student | ref | class | class | 5 | const | 2 | Using where |
+----+-------------+---------+------+---------------+-------+---------+-------+------+-------------+
1 row in set (0.02 sec)
五、SQL优化几个实例
例1、避免where条件使用函数
mysql> explain select * from tt3 where date(t)=CURDATE();
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | tt3 | ALL | NULL | NULL | NULL | NULL | 6 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.03 sec)
这种情况是不会用到索引的,改下SQL即可。
mysql> explain select * from tt3 where t > DATE_FORMAT(CURDATE(),'%Y-%m-%d');
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
| 1 | SIMPLE | tt3 | range | IX_time | IX_time | 4 | NULL | 2 | Using index condition |
+----+-------------+-------+-------+---------------+---------+---------+------+------+-----------------------+
1 row in set (0.02 sec)
mysql> select SQL_NO_CACHE count(*) from test1 where id not in(select id from test2);
+----------+
| count(*) |
+----------+
| 215203 |
+----------+
1 row in set (5.81 sec)
mysql> select SQL_NO_CACHE count(*) from test1 where not exists (select * from test2 where test2.id=test1.id);
+----------+
| count(*) |
+----------+
| 215203 |
+----------+
1 row in set (5.25 sec)
mysql> select SQL_NO_CACHE count(*) from test1 left join test2 on test1.id=test2.id where test2.id is null;
+----------+
| count(*) |
+----------+
| 215203 |
+----------+
1 row in set (4.63 sec)