测试表:CREATETABLE`table_1`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`title`textNOTNULL,`category_id`int(10)unsignedNOTNULL,PRIMARYKEY(`id`))ENGINE=InnoDB;其中id字段是自增主键插入30行用于测试的数据:insertintotable_1(`category_id`)values(1);insertintotable_1(`category_id`)values(1);insertintotable_1(`category_id`)values(1);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(2);insertintotable_1(`category_id`)values(3);insertintotable_1(`category_id`)values(3);insertintotable_1(`category_id`)values(3);insertintotable_1(`category_id`)values(4);insertintotable_1(`category_id`)values(4);insertintotable_1(`category_id`)values(4);insertintotable_1(`category_id`)values(5);insertintotable_1(`category_id`)values(5);insertintotable_1(`category_id`)values(5);执行查询:mysql>explainselect*from`table_1`orderby`id`DESClimit0,5;+----+-------------+---------+-------+---------------+---------+---------+------+------+-------+|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|+----+-------------+---------+-------+---------------+---------+---------+------+------+-------+|1|SIMPLE|table_1|index|NULL|PRIMARY|4|NULL|5||+----+-------------+---------+-------+---------------+---------+---------+------+------+-------+1rowinset这个很好理解,因为id是主键,查询中只使用了orderbyid,查询涉及记录行数rows5,因为limit0,5mysql>explainselect*from`table_1`where`category_id`=2orderby`id`DESClimit0,5;+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+|1|SIMPLE|table_1|index|NULL|PRIMARY|4|NULL|5|Usingwhere|+----+-------------+---------+-------+---------------+---------+---------+------+------+-------------+1rowinset这个就无法理解了,为什么使用了wherecategory_id=2,用一个非索引字段where,该查询涉及的记录数仍然是5?将category_id=2改为任何数字,rows都为5,实际记录前几条并不是category_id=2,按理应该先跳过category_id!=2的然后筛选出符合的结果返回,这样涉及的行数应该大于5啊更无法理解的是,如果使用该表category_id建立索引,同样该SQL执行结果:mysql>explainselect*from`table_1`where`category_id`=2orderby`id`DESClimit0,5;+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+|id|select_type|table|type|possible_keys|key|key_len|ref|rows|Extra|+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+|1|SIMPLE|table_1|ref|category_id|category_id|4|const|18|Usingwhere|+----+-------------+---------+------+---------------+-------------+---------+-------+------+-------------+1rowinset也就是wherecategory_id=2涉及行数成了category_id=2记录的总数!也就是18条那么如果数据库中有1千万条数据,均分至category_id1-10的话,这时候需要执行:select*from`table_1`where`category_id`=2orderby`id`DESClimit0,5;是否需要建立category_id索引呢?如果建立每次都要扫描100万条索引记录吗?如果不建立任何索引,该SQL是否会存在性能问题?
米琪卡哇伊
侃侃无极
相关分类