SELECT读取50 000行/秒的天数从不插入

时间:2013-12-14 10:19:34

标签: mysql sql database-design database-migration

我正在尝试规范化我的数据库。我已经分解了所有冗余数据,现在正在加入并插入新数据。我一次移植了100万行,直到现在还运行良好。现在一百万行需要几天而不是几分钟,并且它会在读取数百万行时陷入困境,而且永远不会进入插入部分。

我有这个查询:

INSERT IGNORE INTO bbointra_normalized.entry (DATE,keyword,url,POSITION,competition,searchEngine) SELECT DATE(insDate) AS DATE,k.id AS kid ,u.id uid, POSITION, competition ,s.id AS sid FROM oldSingleTabels.tempData 
INNER JOIN bbointra_normalized.keyword k ON tempData.keyword = k.keyword
INNER JOIN bbointra_normalized.searchEngine s ON tempData.searchEngine = s.searchEngine
INNER JOIN bbointra_normalized.urlHash u ON tempData.url = u.url
GROUP BY k.id, s.id, u.id ORDER BY k.id, s.id, u.id

说明:

    id  select_type  table     type    possible_keys                                 key           key_len  ref                             rows  Extra                                         
------  -----------  --------  ------  --------------------------------------------  ------------  -------  ----------------------------  ------  ----------------------------------------------
     1  SIMPLE       s         index   (NULL)                                        searchEngine  42       (NULL)                           539  Using index; Using temporary; Using filesort  
     1  SIMPLE       k         index   (NULL)                                        keyword       42       (NULL)                         17652  Using index; Using join buffer                
     1  SIMPLE       tempData  ref     keyword_url_insDate,keyword,searchEngine,url  keyword       767      func                             433  Using where                                   
     1  SIMPLE       u         ref     url                                           url           767      oldSingleTabels.tempData.url       1  Using index                         

显示INNODB状态:

--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 4245, id 140024097179392, state: waiting for server activity
Number of rows inserted 26193732, updated 0, deleted 0, read 3383512394
0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 39676.56 reads/s

用于输入的SQL:

   CREATE TABLE `entry` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `insDate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      `date` int(11) NOT NULL,
      `project` int(11) NOT NULL,
      `keyword` int(11) NOT NULL,
      `url` int(11) NOT NULL,
      `position` int(11) NOT NULL,
      `competition` int(11) NOT NULL,
      `serachEngine` int(11) NOT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `unikt` (`date`,`keyword`,`position`,`serachEngine`)
    ) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci;

4 个答案:

答案 0 :(得分:0)

尝试删除GROUP BY和ORDER BY子句,它们很难处理,似乎没有添加任何值。

如果表bbointra_normalized.entry上有索引,请尝试暂时删除这些索引,因为在插入多行时更新索引是一个繁重的过程。

答案 1 :(得分:0)

在每个INSERT / UPDATE MySQL更新表的索引。这很慢。

如果您正在执行大量INSERT / UPDATE,则应禁用密钥,因此仅重新计算索引一次,而不是每次插入/更新的行。

以下是:

SET FOREIGN_KEY_CHECKS=0
-- Your INSERT/UPDATE statement here
SET FOREIGN_KEY_CHECKS=1

答案 2 :(得分:0)

您需要添加一些索引 - 您链接的每个字段也需要它自己的索引

ALTER TABLE `entry` ADD KEY (`keyword`);
ALTER TABLE `entry` ADD KEY (`searchEngine`);
ALTER TABLE `entry` ADD KEY (`urlHash`);

看起来非常像第一个是最需要的那个

答案 3 :(得分:0)

正如许多人所指出的那样,由于这是一个读取问题,我打破了SELECT查询并测试了查询减去当时的一个连接,我期待巨大的URL表/键成为问题,但很快就发现主要问题是关键字表上的表/索引损坏。我不知道如何发生这种情况,但是在删除并重新创建该表之后,事情就变得非常好了。

我后来接受了@ abasterfield的建议并在Entry表中添加了3个索引,这加快了选择。