Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.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 更好地优化了针对50000多条记录的SELECT SQL查询_Mysql_Sql - Fatal编程技术网

Mysql 更好地优化了针对50000多条记录的SELECT SQL查询

Mysql 更好地优化了针对50000多条记录的SELECT SQL查询,mysql,sql,Mysql,Sql,我有一个查询,它适用于1000条或更少的记录,但现在我需要对50000条以上的记录进行优化,当我在上面运行它时,它只是暂停 这是我的密码: SELECT b1.account_num,b1.effective_date as ed1,b1.amount as am1, b2.effective_date as ed2,b2.amount as am2 FROM bill b1 left join bill b2 on (b1.account_num=b2.account_num) where

我有一个查询,它适用于1000条或更少的记录,但现在我需要对50000条以上的记录进行优化,当我在上面运行它时,它只是暂停

这是我的密码:

SELECT  
b1.account_num,b1.effective_date as ed1,b1.amount as am1,
b2.effective_date as ed2,b2.amount as am2
FROM bill b1
left join bill b2 on (b1.account_num=b2.account_num)
where b1.effective_date = (select max(effective_date) from bill where account_num = b1.account_num)
and (b2.effective_date = (select max(effective_date) from bill where account_num = b1.account_num and effective_date < (select max(effective_date) from bill where account_num = b1.account_num)) or b2.effective_date is null)
ORDER BY b1.effective_date DESC
我的目标是从一个包含多条记录的表中获取最新的两个生效日期和金额

首先,内部预查询获取每个帐户的最大日期。然后将其加入到每个帐户的账单表中,并且生效日期小于已检测到的最大值

然后将其加入各自的账单中,以获得相应的金额

select
      FB1.account_num,
      FB1.effective_date as ed1,
      FB1.amount as am1,
      FB2.effective_date as ed2,
      FB2.amount as am2
   from
      ( select
              pq1.account_num,
              pq1.latestBill,
              max( b2.effective_date ) as secondLastBill
           from
              ( SELECT  
                      b1.account_num,
                      max( b1.effective_date ) latestBill
                   from
                      bill b1
                   group by
                      b1.account_num ) pq1
                 LEFT JOIN bill b2
                    on pq1.account_num = b2.account_num
                   AND b2.effective_date < pq1.latestBill 
            group by
               pq1.account_num ) Final
         JOIN Bill FB1
            on Final.Account_Num = FB1.Account_Num
            AND Final.LatestBill = FB1.Effective_Date

         LEFT JOIN Bill FB2
            on Final.Account_Num = FB2.Account_Num
            AND Final.secondLastBill = FB2.Effective_Date
   ORDER BY
      Final.latestBill DESC

在mysql中,没有像row_number这样的窗口分析函数,因此我们可以使用变量模拟相同的函数

好的是,使用这种方法只能扫描一次表

将为每个分区分配一个行_编号,该编号根据帐号、生效日期进行划分,并且每个分区仅选择2行

select  account_num,
        max(case when row_number =1 then effective_date end) as ed1,
        max(case when row_number =1 then amount end) as am1,
        max(case when row_number =2 then effective_date end) as ed2,
        max(case when row_number =2 then amount end )as am2

from (
select account_num, effective_date, amount,
      @num := if(@prevacct= account_num , @num + 1, 1) as row_number,
      @prevacct := account_num as dummy
from bill, (select @num:=0, @prevacct := '' ) as var
order by account_num , effective_date desc
 )T
where row_number <=2
group by account_num

附加EXPLAIN query planner outputI我通常发现MySQL优化联接比优化相关子查询更好,尽管我听说在最新版本中效果更好。删除或b2.effective_date为null是否会对结果产生任何影响!?!?下面是SQL小提琴:…但没有期望的结果:-