簡體   English   中英

即使使用索引,連接兩個表 MySQL 也很慢

[英]Joining two tables MySQL is slow even with indexing

我有兩個表:

第一個table1是動態創建的(當用戶從​​ Web 服務器提交數據時),通常是大約 50K 行。 第二個表是一個查找表table2 ,有大約 10Mil 行。

我正在嘗試將兩個表連接到四列,如下所示:

SELECT t.id FROM table1 t 
JOIN table2 m
ON (t.name = m.name AND t.pos = m.pos AND t.ref = m.ref AND t.alt = m.alt);

我在table2對列name (VARCHAR)、 pos (INT)、 ref (CHAR) 和alt (CHAR) 進行了索引,但查詢仍然需要很長時間才能完成。

關於這里可能出現什么問題的任何指示?

謝謝


EXPLAIN輸出:

id  select_type table   partitions  type    possible_keys   key key_len ref rows    filtered    Extra
1   SIMPLE  t1  NULL    ALL NULL    NULL    NULL    NULL    49329   100.00  Using where
1   SIMPLE  t2  NULL    ref table2_name,table2_pos,table2_ref,table2_alt    table2_name 32  my_db.t1.NAME   2488    0.00    Using index condition; Using where

name, pos, ref, alt上創建復合索引

喜歡

INDEX theIndex (name,pos,ref, alt)

此外,4 個單一索引會有所幫助 - 請參閱http://dev.mysql.com/doc/refman/5.7/en/index-merge-optimization.html - 但不如復合索引那么多。

在這里嘗試兩件事:

  1. 第一個是最簡單的——更改 join 子句的順序以將 varchar 列移到末尾。

SELECT t.id FROM table1 t JOIN table2 m ON (t.pos = m.pos AND t.ref = m.ref AND t.alt = m.alt AND t.name = m.name);

  1. 這需要做更多的工作,但添加一個新的計算列,該列基於 4 列生成數字哈希。 刪除 pos、ref、alt 和 name 上的索引,並向哈希列添加新索引。 然后在您的連接子句中包含哈希列。

SELECT t.id FROM table1 t JOIN table2 m ON (t.hash = m.hash AND t.pos = m.pos AND t.ref = m.ref AND t.alt = m.alt AND t.name = m.姓名);

編輯:不查看您的數據庫和查詢執行計划,很難解決這個問題,但我的猜測是 MySQL 很難加入 VARCHAR 列。 你能用結果更新你的問題嗎

EXPLAIN SELECT t.id FROM table1 t JOIN table2 m ON (t.name = m.name AND t.pos = m.pos AND t.ref = m.ref AND t.alt = m.alt)

任何表的索引:

SELECT 
  CONCAT(
    'ALTER TABLE ', 
    TABLE_NAME, 
    ' ', 
    'ADD ', 
    IF(
      NON_UNIQUE = 1, 
      CASE UPPER(INDEX_TYPE) WHEN 'FULLTEXT' THEN 'FULLTEXT INDEX' WHEN 'SPATIAL' THEN 'SPATIAL INDEX' ELSE CONCAT(
        'INDEX ', INDEX_NAME, ' USING ', INDEX_TYPE
      ) END, 
      IF(
        UPPER(INDEX_NAME) = 'PRIMARY', 
        CONCAT(
          'PRIMARY KEY USING ', INDEX_TYPE
        ), 
        CONCAT(
          'UNIQUE INDEX ', INDEX_NAME, ' USING ', 
          INDEX_TYPE
        )
      )
    ), 
    '(', 
    GROUP_CONCAT(
      DISTINCT CONCAT('', COLUMN_NAME, '') 
      ORDER BY 
        SEQ_IN_INDEX ASC SEPARATOR ', '
    ), 
    ');'
  ) AS 'Show_Add_Indexes' 
FROM 
  information_schema.STATISTICS 
WHERE 
  TABLE_SCHEMA = 'your_database' 
  and TABLE_NAME = 'your_table';
-- GROUP BY 
--   TABLE_NAME, 
--   INDEX_NAME 
-- ORDER BY 
--   TABLE_NAME ASC, 
--   INDEX_NAME ASC;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM