MYSQL 加速查询

标签 mysql

美好的一天。 我的任务是尝试加快一些运行缓慢的查询,但作为 MYSQL 新手,我不确定我是否已经取得了最好的结果。我意识到论坛上已经充斥着这些类型的问题,而且我已经通读了其中的很多内容,但如果可能的话,我仍然希望得到进一步的帮助。

我通过剥离连接并首先尝试加速基本选择来开始优化过程。该表中有大约 4 400 000 个条目,查询返回大约 1 800 000 个条目。

我从这个开始:

select  
   ID,
   CallStarted,
   CallDirection 
from 
   TRMSMain.tblcalldata CALLDATA  
   where CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59' 
ORDER BY ID DESC LIMIT 0 , 50;

大约用了 360 秒。 然而,这需要 2 秒:

select
  ID,
  CallStarted,
  CallDirection 
from 
  TRMSMain.tblcalldata CALLDATA  
where CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59' 
LIMIT 0 , 50;

虽然最后一个查询返回了范围内的前 50 个,而不是最后 50 个,这让我相信“order by desc”操作非常昂贵。 然后我摆弄了一下并想出了以下方法(当然这不是唯一的方法),这需要 20 到(有时)40 秒:

use trmsmain;
RESET QUERY CACHE;
drop procedure if exists intTest;
delimiter #
create procedure intTest()
BEGIN
    declare lastID int unsigned default 0;
    declare frstID int unsigned default 0;
    select
        (select max(ID) from trmsmain.tblcalldata where  (CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59'))
        into lastID;
    set     frstID = lastID - 49;
    CREATE TEMPORARY TABLE IF NOT EXISTS table2 (index (ID)) AS
    (       
        select
            ID,
            CallStarted,
            CallDirection
        from
            trmsmain.tblcalldata CALLDATA  
        where
            ID between frstID AND lastID
    );
    select * from table2 order by ID desc;
END #
delimiter ;
call intTest();

结果正是我需要的,callstarted 是一个索引字段,但我的问题是这种性能是否可以接受(我能期望的最好)。我的 PC 是中档,有 4GB 内存。

请指教。 谢谢。

更多信息:

我的 SQL 脚本等同于此:

select
    ID,
    CallStarted,
    CallDirection
  from trmsmain.tblcalldata CALLDATA  

where  ID between (select(select max(ID) from trmsmain.tblcalldata  where  (CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59'))  - 49) AND 
(select max(ID) from trmsmain.tblcalldata   where  (CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59'));

我只是按照我的方式做的,因为我想看看上面是否会重新使用 MAX 的结果,所以我将上面的结果与脚本的结果(相似)进行了比较。

在我看了他的解释后,我感到很困惑,并删除了所有索引,除了 callstarted 上的索引。 ID为主键。

只有一个索引可以将时间缩短到一秒。即使使用“force index(callstarted),我也无法接近这个结果。

不知何故,我现在更加困惑了。

问候

最佳答案

如果您知道 id 是按顺序分配的,您可以试试这个:

select ID, CallStarted, CallDirection 
from TRMSMain.tblcalldata CALLDATA  cd JOIN
     (select MIN(id) as minid, MAX(id) as maxid
      from TRMSMain.tblcalldata CALLDATA cd2
      where CallStarted BETWEEN '2014-02-10' AND '2014-05-11 23:59:59'
     ) s
     on cd.id >= minid and cd.id <= maxid
order by id desc
limit 0, 50;

如果 MySQL 足够聪明,可以同时为 onorder by 使用索引,那么性能可能会比您的版本更快。

尝试在 TRMSMain.tblcalldata(CallsStarted) 上创建索引。

关于MYSQL 加速查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27901783/

相关文章:

python - python 导入时出现 SWIG 错误 'undefined symbol: mysql_query'

MySQL存储过程返回表

php - 自动同步 Laravel 中的相关表

php - 如何在 PHP 中获取 XML 文件的值?

php - Magento 将用户注册限制为特定电子邮件域

php - 在 php 中按下按钮时选择特定的 id

mysql - 使用 MySQL 将 LIKE 与存储过程参数连接起来

mysql - SQL 触发器是否按顺序运行?

php - 如何避免选择所有行显示相同值的列(SQL 查询)

mysql自动增量值没有按顺序更新