2016-05-24 60 views
2

連接時速度很慢,我們有兩個表:MySQL在複合鍵

SELECT B.x 
FROM B 
INNER JOIN A 
    ON A.b = B.b 
    AND A.c = B.c 
WHERE A.a IN (...a values...); 

a values從客戶端語言給(我們的情況:紅寶石)

create table A (
    id int, 
    a int, 
    b int, 
    c varchar(255), 
    unique key K1 (a,c), 
    key K2 (b,c), 
    key K3 (a,b,c) 
); 
create table B (
    id int, 
    b int, 
    c varchar(255), 
    x varchar(255), 
    unique key K (b,c) 
); 

像運行查詢,以及有關10-100,000個項目。

解釋是這樣的。

*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: A 
     type: range 
      key: K 
     key_len: 4 
      ref: NULL 
     rows: 100 
     Extra: Using where; Using index 
*************************** 2. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: app_devices 
     type: ref 
      key: K 
     key_len: 4 
      ref: A.b 
     rows: 213 
     Extra: Using index condition 
2 rows in set (0.00 sec) 

當A和B很小時,這個查詢很好用,但當表大小超過2000萬行時,這個查詢變得很慢。 我懷疑組合鍵在加入時工作不正常。我該如何解決這個問題?

+0

你應該閱讀MySQL索引的[** ** TIPS(http://mysql.rjweb.org/doc.php/index_cookbook_mysql) –

+0

你的意思是'WHERE的AA(一...值...);'可以是100K的值?這對於索引搜索來說似乎並不理想。就像你加入'表A'和'Avalues'一樣,但'Avalues'沒有索引。你也沒有A'(b,c)'的合成索引,所以你的連接'ON'沒有使用正確的索引 –

+0

'(... a values ...)'實際上就是'(12,16,295,1053) '。 '(b,c)'存在,但我省略了,因爲優化器沒有使用它,對不起。我已編輯添加所有索引。 – mtomita

回答

1

C是一個VARCHAR(255)的索引,它在長度上相當大,並且還包含所有不包含數字的字符。如果VARCHAR的長度始終爲255,則應將其設置爲CHAR,以查看該展會的具體情況。

但是,如果您有2000萬行,這意味着您的自動增量ID將只有8個長度,並且只會包含數字,這更適合您的連接。 把這個ID放在桌子上;

create table A (
    id int, 
    a int, 
    b int, 
    c varchar(255), 
    b_id int, //additional field 
    unique key K1 (a,c), 
    key K2 (b,c), 
    key K3 (a,b,c) 
); 
create table B (
    id int, 
    b int, 
    c varchar(255), 
    x varchar(255), 
    unique key K (b,c) 
); 

然後,一旦運行這個命令:

UPDATE a  
INNER JOIN B 
ON A.b = B.b 
AND A.c = B.c 
SET a.b_id = b.id 

然後將查詢變爲:

SELECT B.x 
FROM B 
INNER JOIN A 
ON A.b_id = b.id 
WHERE A.a IN (...a values...); 

這應該在一個合理的時間運行

編輯:

是您varchar(255)總是2 55長,還是可以更短?你可以縮短它。

如果您在不鎖定的情況下將包含所有記錄的表複製,並對副本執行添加自動增量更新,並且在短暫停機時間內(如果可能)將其重命名爲原始數據庫。

您可以使用以下問題來了解這是否適合您。 :

Surrogate vs. natural/business keys

+0

謝謝,我試了一下,並確認性能變好了,但是我們的編寫器服務非常繁忙,所以添加自動增量id獲取和更新可能會增加成本(因爲A記錄是在B之前創建的,所以A需要更新。出價)。讓我想想... – mtomita