Create Table: CREATE TABLE `zz_info` (
  `tid` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL COMMENT '标题',
  `uid` int(11) NOT NULL DEFAULT '0' COMMENT 'UID',
  `c1` int(11) NOT NULL DEFAULT '0' COMMENT '类目1',
  `c2` int(11) NOT NULL DEFAULT '0' COMMENT '类目2',
  `c3` int(11) NOT NULL DEFAULT '0' COMMENT '类目3',
  `d1` int(11) NOT NULL DEFAULT '0' COMMENT '地区1',
  `d2` int(11) NOT NULL DEFAULT '0' COMMENT '地区2',
  `d3` int(11) NOT NULL DEFAULT '0' COMMENT '地区3',
  `addtime` int(11) NOT NULL COMMENT '发布时间',
  `uptime` int(11) NOT NULL COMMENT '更新时间',
  `status` smallint(6) NOT NULL DEFAULT '1' COMMENT '信息状态,默认1显示中',
  PRIMARY KEY (`tid`),
  KEY `idx-info-uid` (`uid`),
  KEY `idx-info-c1` (`c1`),
  KEY `idx-info-c2` (`c2`),
  KEY `idx-info-c3` (`c3`),
  KEY `idx-info-d1` (`d1`),
  KEY `idx-info-d2` (`d2`),
  KEY `idx-info-d3` (`d3`),
  KEY `idx-info-status` (`status`),
  KEY `uptime` (`uptime`),
  KEY `idx-info-status-c2` (`status`,`c2`),
  KEY `idx-info-status-d1` (`status`,`d1`),
  KEY `idx-info-status-c1` (`status`,`c1`),
  KEY `idx-info-status-d2` (`status`,`d2`),
  KEY `idx-info-status-c2-d2` (`status`,`c2`,`d2`)
) ENGINE=InnoDB AUTO_INCREMENT=16538560 DEFAULT CHARSET=utf8
/*!50100 PARTITION BY HASH (tid)
PARTITIONS 10 */
1 row in set (0.00 sec)
以上一个数据表, idx-info-d1 与 idx-info-status-d1 是否有重复?是否是在 idx-info-status-d1 中包含了 idx-info-d1?会出现以下几类查询SQL:d1单独查询、d2单独查询、d1与status组合、d2与status组合、d2+c2+status 组合、c1+status、c2+status

解决方案 »

  1.   


    (`d1`) 与 (`status`,`d1`) 不重复。最左匹配原则。,
      

  2.   

    不会重复的,只有索引中的字段完全一样,且顺序也一样的时候,才是重复的。另外,会出现以下几类查询SQL:d1单独查询、d2单独查询、d1与status组合、d2与status组合、d2+c2+status 组合、c1+status、c2+status。那么, KEY `idx-info-c1` (`c1`),
      KEY `idx-info-c2` (`c2`),
      KEY `idx-info-c3` (`c3`),
     KEY `idx-info-c1` (`d3`)这几个索引就多余了把
      

  3.   

    另外:d1单独查询、d2单独查询、d1与status组合、d2与status组合这几个索引,也可以合并成2个索引:d1与status组合、d2与status组合
      

  4.   


    如果我查询where是  d1+status / d2+status 
    示例:where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333' 这样情况下,只需要加 status-d2 status-d3复合索引,而单独给status、d2、d3加索引是不起作用的吗?
      

  5.   


    现在还出现一个问题,查询 show processlist ,执行的语句中如果有 order by 就一直出现 `Sorting result`的提示,延迟100多秒。是否是因为 order by 主键id,而主键又用给了分表 partition by hash(id) 导致如果用主键做排序,反而效率还不如索引uptime 来排序
      

  6.   


    如果我查询where是  d1+status / d2+status 
    示例:where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333' 这样情况下,只需要加 status-d2 status-d3复合索引,而单独给status、d2、d3加索引是不起作用的吗如果你是在where里面有2个字段的查询条件,那么复合索引,也就是2个字段的索引,效率更高,msyql一般不会用你建的单个字段的索引。另外,where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333'  这种,建索引适合建d2+status,d3+status这样的索引,把status放到后面,因为status的查询条件是in的
      

  7.   


    如果我查询where是  d1+status / d2+status 
    示例:where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333' 这样情况下,只需要加 status-d2 status-d3复合索引,而单独给status、d2、d3加索引是不起作用的吗如果你是在where里面有2个字段的查询条件,那么复合索引,也就是2个字段的索引,效率更高,msyql一般不会用你建的单个字段的索引。另外,where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333'  这种,建索引适合建d2+status,d3+status这样的索引,把status放到后面,因为status的查询条件是in的
    如果创建的符合索引是  d2-status,那使用 where d2='111' and status in(0,1,2) 和 where status in(0,1,2) and d2='111' 会有差别吗?mysql是否会自动的优先去查d2-status 的索引呢
      

  8.   


    如果我查询where是  d1+status / d2+status 
    示例:where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333' 这样情况下,只需要加 status-d2 status-d3复合索引,而单独给status、d2、d3加索引是不起作用的吗如果你是在where里面有2个字段的查询条件,那么复合索引,也就是2个字段的索引,效率更高,msyql一般不会用你建的单个字段的索引。另外,where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333'  这种,建索引适合建d2+status,d3+status这样的索引,把status放到后面,因为status的查询条件是in的
    如果创建的符合索引是  d2-status,那使用 where d2='111' and status in(0,1,2) 和 where status in(0,1,2) and d2='111' 会有差别吗?mysql是否会自动的优先去查d2-status 的索引呢?还是说必须按照创建索引的顺序进行 where,即 d2必须在前面,status必须在后面才最优吗
      

  9.   


    如果我查询where是  d1+status / d2+status 
    示例:where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333' 这样情况下,只需要加 status-d2 status-d3复合索引,而单独给status、d2、d3加索引是不起作用的吗如果你是在where里面有2个字段的查询条件,那么复合索引,也就是2个字段的索引,效率更高,msyql一般不会用你建的单个字段的索引。另外,where status in(0,1,2) and d2 ='222' ,where status in (0,1,2) and d3='333'  这种,建索引适合建d2+status,d3+status这样的索引,把status放到后面,因为status的查询条件是in的
    如果创建的符合索引是  d2-status,那使用 where d2='111' and status in(0,1,2) 和 where status in(0,1,2) and d2='111' 会有差别吗?mysql是否会自动的优先去查d2-status 的索引呢?还是说必须按照创建索引的顺序进行 where,即 d2必须在前面,status必须在后面才最优吗
    一般来说,创建索引,是要根据具体的sql来创建的,如果你的sql是这样的 where d2='111' and status in(0,1,2) 和 where status in(0,1,2) and d2='111' ,实际上对mysql来说,这2个where条件是等价的,没区别,那么最优的创建索引的是:d2-status。