Mysql

數據庫和查詢優化

  • March 21, 2013

我有一個包含三個表的數據庫:tbl_database(主表是主表)、tbl_cmdatabase 和 tbl_blacklist。這三個表共享相同的結構,但可以記錄的數量不同。這是SQL結構,基本上是一樣的:

CREATE TABLE IF NOT EXISTS `tbl_ndatabase` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `id_telefonica` int(11) NOT NULL,
 `number` varchar(11) COLLATE utf8_spanish2_ci NOT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_spanish2_ci AUTO_INCREMENT=1 ;

表 tbl_database 包含約 194 074 條記錄,它們應該繼續大量增長,表 tbl_cmdatabase 包含約 45,742 條記錄,並且類似地可以增加,但可能不會像 tbl_database 那樣誇張,但會增加,最後表 tbl_blacklist 有約 92,038 條記錄。我正在開發一個應用程序,我需要驗證我將插入表 tbl_database 的數字不在表 tbl_blacklist 和 tbl_cmdatabase 中,所以我需要檢查每一行以查找數字(這個查詢在這個數量的記錄中很慢) . 我需要做的是優化一些表或更改結構,因為當我執行這些查詢時,由於共享主機不支持大型查詢,伺服器往往會下降,任何人都可以幫助我解決這個問題嗎?有什麼建議?

**編輯:**添加了測試數據文件

繼前面的討論和@Frustrated 提供的答案之後,這是我對儲存過程提出的建議:

CREATE PROCEDURE insertNumber(IN newNum VARCHAR(11))
BEGIN
   DECLARE i int;
   SELECT COUNT(*) INTO i
       FROM
       (
           SELECT `number` FROM `tbl_blacklist` WHERE `number`=newNum
           UNION
           SELECT `number` FROM `tbl_cmdatabase`  WHERE `number`=newNum
       ) AS t1;
   IF i = 0 THEN
       INSERT INTO `tbl_database` (`number`) VALUES (newNum);
   END IF;
END;

我在 MySQL 5.5.29 下通過發出類似的命令對其進行了測試CALL insertNumber('123-1234');,它似乎工作得很好。

或者,也許將相同的邏輯放在 INSERT 觸發器中可能更方便:

CREATE TRIGGER checkLists 
BEFORE INSERT ON `tbl_database`
FOR EACH ROW
BEGIN
   DECLARE i int;
   SELECT COUNT(*) INTO i
       FROM
       (
           SELECT bl.`number` FROM `tbl_blacklist` bl
               WHERE bl.`number`=new.`number`
           UNION
           SELECT cm.`number` FROM `tbl_cmdatabase` cm
               WHERE cm.`number`=new.`number`
       ) AS t1;
   IF i > 0 THEN
       SIGNAL SQLSTATE '45000';  # unhandled user-defined exception
   END IF;
END;

顯然,該number列應該在tbl_blacklisttbl_cmdatabase表中都建立索引。

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