Mysql

遺留應用程序的 MySQL 查詢優化

  • March 28, 2014

我正在使用一個遺留應用程序,該應用程序幾年前開始使用少量數據(由第三方自定義為此客戶端開發),現在我們看到 MySQL 負載僅在此查詢上飆升。

多年後他們現在擁有實際數據的事實是我們注意到此時性能受到影響的原因。只是不知道該怎麼處理它。

我試圖確保索引是正確的以及架構中沒有的,但這裡有一個由應用程序生成的範例查詢。有什麼想法可以幫助提高性能嗎?

SELECT id, 
      name, 
      phone 
FROM   customers 
WHERE  ( last_updated >= '2013-03-01' 
        AND last_updated <= '2013-03-27 24:00:00' 
        AND status = '0' 
        AND deadlead = '' 
        AND purchased = '' 
        AND id != 0 ) 
       OR ( status = '0' 
            AND deadlead = '' 
            AND purchased = '' 
            AND id IN (SELECT DISTINCT cid 
                       FROM   notes 
                       WHERE  timestamp >= '2013-03-01' 
                              AND timestamp <= '2013-03-27 24:00:00') 
            AND id != 0 ) 

CREATE TABLE IF NOT EXISTS `customers` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `name` varchar(40) NOT NULL,
 `email` varchar(255) NOT NULL,
 `phone` varchar(20) NOT NULL,
 `alt_phone` varchar(255) NOT NULL,
 `tradein` text NOT NULL,
 `purchased` text NOT NULL,
 `deadlead` text NOT NULL,
 `interest` varchar(255) NOT NULL,
 `trailer` varchar(255) NOT NULL,
 `status` binary(1) NOT NULL,
 `options` text NOT NULL,
 `created_on` date NOT NULL,
 `last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 UNIQUE KEY `id_2` (`id`),
 KEY `id` (`id`),
 KEY `id_3` (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8913 ;

CREATE TABLE IF NOT EXISTS `notes` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `cid` int(11) NOT NULL,
 `uid` int(11) NOT NULL,
 `note` text NOT NULL,
 `file` varchar(255) NOT NULL,
 `timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 `reminder` date NOT NULL,
 `locked` int(1) NOT NULL DEFAULT '0',
 PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=19308 ;

更新:

這是在EXPLAIN查詢中使用的輸出:

解釋聲明

我將補充@RolandoMySQLDBA 提出的建議。

看起來notes.cid 應該是與customers.id 相關的外鍵。

您可以嘗試用 EXISTS 子查詢替換 SELECT DISTINCT 子查詢。select distinct 將查找所有相關的註釋。一個存在可能會表現得更好,因為它只檢查至少一個音符的存在。

-- Current:
AND id IN (SELECT DISTINCT cid 
                       FROM   notes 
                       WHERE  timestamp >= '2013-03-01' 
                              AND timestamp <= '2013-03-27 24:00:00') 




-- suggested replacement:
AND EXISTS (
   SELECT *
   FROM notes
   WHERE notes.cid = customers.id
       AND  notes.timestamp >= '2013-03-01' 
       AND notes.timestamp <= '2013-03-27 24:00:00'
)

引用自:https://dba.stackexchange.com/questions/62018