Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何提高相同表联接的性能?不知何故,没有使用1索引_Mysql - Fatal编程技术网

Mysql 如何提高相同表联接的性能?不知何故,没有使用1索引

Mysql 如何提高相同表联接的性能?不知何故,没有使用1索引,mysql,Mysql,我有一个表格,用于支付每个订阅付款的开始和结束年份 大约有45000条记录 CREATE TABLE `a_payment` ( `user_id` int(11) NOT NULL, `pay_id` int(11) NOT NULL, `start_year` int(11) DEFAULT NULL, `end_year` int(11) DEFAULT NULL, PRIMARY KEY (`pay_id`), KEY `end_year` (`end_year`

我有一个表格,用于支付每个订阅付款的开始和结束年份

大约有45000条记录

CREATE TABLE `a_payment` (
  `user_id` int(11) NOT NULL,
  `pay_id` int(11) NOT NULL,
  `start_year` int(11) DEFAULT NULL,
  `end_year` int(11) DEFAULT NULL,
  PRIMARY KEY (`pay_id`),
  KEY `end_year` (`end_year`),
  KEY `start_year` (`start_year`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
我想查找订阅过期年份的续订计数

它将45000条记录减少到10条,每年1条

select  t1.end_year as year
        , 0 as total
        , count(t1.user_id) as renew
from    a_payment t1
    , a_payment t2
where   t1.user_id = t2.user_id
and t1.end_year = t2.start_year
group by t1.end_year
order by t1.end_year
需要2分58秒

“发送数据”耗时178秒,占99.99962%

描述所显示的select语句

  • 选择类型simple,表t1,类型all,键null,行39267,额外使用where;使用临时设备;使用文件排序
  • 选择简单类型,表t2,类型ref,键起始年,行t1.end年,行7557,使用where

  • 为什么要花这么长时间?为什么不使用年终指数?我需要更改什么以加快速度?

    您没有使用任何筛选条件,因此您的查询需要至少完全读取一个表

    查询可以从索引中受益:

    create index ix1 on a_payment (end_year, user_id);
    
    create index ix2 on a_payment (user_id, start_year);
    
    但从指数来看,最重要的是:

    create index ix1 on a_payment (end_year, user_id);
    
    create index ix2 on a_payment (user_id, start_year);
    
    另外,请使用现代连接语法。您的查询可以重新表述为:

    select  t1.end_year as year
            , 0 as total
            , count(t1.user_id) as renew
    from    a_payment t1
    join    a_payment t2 
         on t1.user_id = t2.user_id and t1.end_year = t2.start_year
    group by t1.end_year
    order by t1.end_year
    

    请使用现代连接语法。您使用的语法来自80年代。添加两个键很有效!为所有3列添加1个键也有效。键
    用户开始/结束/年
    用户id
    开始/年
    结束/年