如何使用Union优化Mysql Select Query?

时间:2015-07-15 10:04:10

标签: php mysql sql database optimization

我正在使用InnoDb存储引擎处理mysql数据库。 我的表结构如下:

表名:archiveincomingsms

enter image description here

索引详情:archiveincomingsms

enter image description here

表名:archiveoutgoingsms enter image description here

索引详情:archiveoutgoingsms enter image description here

以上是我的表格结构及其索引详情!

两个表分别至少有超过10亿条记录(行)。

现在问题是当我想执行以下SqlQuery时:

.htaccess

以上查询需要超过30秒的时间才能从表中获取数据。 另一个是我必须为分页目的计算行数,它也需要超过30秒。

总的来说,执行需要1分钟以上。 有没有适当的方法来优化时间? 我必须进入最多5秒。 !怎么可能? 我正在使用mysql数据库!

3 个答案:

答案 0 :(得分:0)

我看不到索引。

请查询结果:

EXPLAIN (SELECT id AS ID,`recieved_datetime` `Date`,'MT' AS Type,src_adress AS Msisdn,TEXT as text,CHAR_LENGTH(TEXT) AS QtyOfSymbols,'OK' AS `Status` FROM archiveincomingsms
                  WHERE 1=1 AND recieved_datetime BETWEEN '2015-06-14 00:00:00' AND '2015-07-14 23:59:59')
                  UNION ALL
                  (SELECT id AS ID,`send_date` `Date`,'MO' AS Type,scr_adress AS Msisdn,TEXT as text,CHAR_LENGTH(TEXT) AS QtyOfSymbols,'OK' AS `Status` FROM archiveoutgoingsms
                  WHERE 1=1 AND send_date BETWEEN '2015-06-14 00:00:00' AND '2015-07-14 23:59:59') ORDER BY `Date` ASC LIMIT 0 ,100

什么是使用时

ORDER BY `id` ASC

insted的

ORDER BY `Date` ASC

答案 1 :(得分:0)

enter image description here 以下是此查询说明的结果!

图片可以通过在新标签页中打开来查看!这里太小了!

答案 2 :(得分:0)

请提供SHOW CREATE TABLE archiveincomingsms; - 您提供的信息更清晰,更易读。此外,它还显示了引擎和索引。

对于UNION,您需要

INDEX(send_date),
INDEX(received_date)

但是,由于您正在查看一个月的数据,这可能是该表的重要组成部分。如果它超过表的20%,它将进行表扫描(或两次扫描),这意味着UNION没有帮助。

旁注:而不是

          AND  send_date BETWEEN '2015-06-14 00:00:00'
                             AND '2015-07-14 23:59:59'

这将更清洁,更容易:

          AND  send_date >= '2015-06-14'
          AND  send_date <  '2015-06-14' + INTERVAL 1 MONTH

它会自动处理短月和年的边界。

表名很难区分;它们看起来都像

archivemiscellanyms 

哦,我还没完呢(现在我盯着桌上的名字看他们不一样了)......

ORDER BY...LIMIT添加到UNION的每个部分:

( SELECT ... ORDER BY received_datetime LIMIT    100 )
UNION ALL
( SELECT ... ORDER BY send_date         LIMIT    100 )
ORDER BY date                           LIMIT 0, 100

如果你打算“分页”(畏缩),那么就这样做,比如第3页:

( SELECT ... ORDER BY received_datetime LIMIT      300 )
UNION ALL
( SELECT ... ORDER BY send_date         LIMIT      300 )
ORDER BY date                           LIMIT 200, 100

现在索引可用。但是,当用户从一个页面到另一个页面时,它将变得越来越慢。

你可以 通过“记住你离开的地方”来加速后续页面。见my pagination blog;