我正在使用InnoDb存储引擎处理mysql数据库。 我的表结构如下:
表名:archiveincomingsms
索引详情:archiveincomingsms
表名:archiveoutgoingsms
索引详情:archiveoutgoingsms
以上是我的表格结构及其索引详情!
两个表分别至少有超过10亿条记录(行)。
现在问题是当我想执行以下SqlQuery时:
.htaccess
以上查询需要超过30秒的时间才能从表中获取数据。 另一个是我必须为分页目的计算行数,它也需要超过30秒。
总的来说,执行需要1分钟以上。 有没有适当的方法来优化时间? 我必须进入最多5秒。 !怎么可能? 我正在使用mysql数据库!
答案 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)
以下是此查询说明的结果!
图片可以通过在新标签页中打开来查看!这里太小了!
答案 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;