MySQL分区表简介
http://dev.mysql.com/doc/refman/5.1/zh/partitioning.html#partitioning-list
今天有一个需求,审核图片是否违规,
需要查询尚未审核的图片.
其中status 1表示尚未审核;0表示已经审核;-1表示未通过审核
初始化实验数据:
-
drop table if exists t;
-
create table t(
-
id int auto_increment primary key,
-
pictureURL varchar(10),
-
status int,
-
createtime datetime
-
);
-
-
drop procedure if exists initData;
-
-
delimiter $$
-
create procedure initData()
-
begin
-
set @index=0;
-
while @index<10000000 do
-
insert into t(createtime) values(now()-interval @index second);
-
set @index:=@index+1;
-
end while;
-
commit;
-
end$$
-
delimiter ;
-
-
call initData();
-
update t set status=0;
-
update t set status=1 where mod(id,9)=0;
-
commit;
实验假设表中有1kw记录,尚未通过审核的数据占全部数据的十分之一左右.

现在需要查询这些尚未通过审核的数据信息。
这种需求还是很常见的.
如果是Oracle数据库,可以使用函数索引解决这个问题
http://blog.itpub.net/29254281/viewspace-775791/
但是很明显,MySQL没有这个功能.
由于结果集很大,MySQL会倾向于全表扫描这个表.效率很低.

这种情况下,即使status字段创建索引也没有任何效果,反而降低性能.
这个时候,可以考虑使用List分区表处理.
但是status要作为主键的一部分,这样只能是联合主键,对于使用Hibernate的项目,这个改动还是很烦人的.
(分区的字段必须是主键的一部分)
-
drop table if exists t1;
-
create table t1(
-
id int auto_increment,
-
pictureURL varchar(10),
-
status int,
-
createtime datetime,
-
primary key(id,status)
-
)
-
partition by list(status)
-
(
-
partition s0 values in (0),
-
partition s1 values in (1),
-
partition s2 values in (2),
-
partition other values in (null)
-
);
-
-
insert into t1 select * from t;
-
commit;
使用List分区表之后,该场景的性能大幅提升

主要是应用了分区消除,从原来的全表扫描,变成了全分区扫描.


这样扫描的数据从689M降为了57M
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-1281084/
,如需转载,请注明出处,否则将追究法律责任。