2017-02-14 74 views
0

everyone。這是我的MySQL服務器中的一個問題。
我有一張約40,000,000行和10列的表格。
它的大小約爲4GB,引擎是innodb。
它是一個主數據庫,只執行一個這樣的sql。在mysql中拆分表的性能

insert into mytable ... on duplicate key update ... 

約99%sqls執行update部分。

現在服務器變得越來越慢。 我聽說拆分表可能會提高其性能。然後我在我的個人電腦上試了一下,分成10個表,失敗了,也嘗試了100,失敗了。速度反而變慢了。所以我想知道爲什麼拆分表不會提高性能?

在此先感謝。

更多細節:

CREATE TABLE my_table (
    id BIGINT AUTO_INCREMENT, 
    user_id BIGINT, 
    identifier VARCHAR(64), 
    account_id VARCHAR(64), 
    top_speed INT UNSIGNED NOT NULL, 
    total_chars INT UNSIGNED NOT NULL, 
    total_time INT UNSIGNED NOT NULL, 
    keystrokes INT UNSIGNED NOT NULL, 
    avg_speed INT UNSIGNED NOT NULL, 
    country_code VARCHAR(16), 
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    PRIMARY KEY(id), UNIQUE KEY(user_id) 
); 

PS:
我也試圖與固態硬盤和硬盤驅動器不同的計算機上,但並沒有幫助過。

回答

0

嘗試使用mysql代理將數據庫拆分爲一些mysql實例,就像mysql-proxy或haproxy而不是一個mysql實例。也許你可以有很棒的表現。

+0

但是我的公司沒有太多的預算用於更多的實例。有什麼辦法可以嘗試嗎?多謝 –

+0

你可以嘗試備份一些數據並刪除它們,如果你的業務被允許的話 –

+0

或者你可以將你的表分成7個或更多的表。每天閱讀一張表並備份並清除其他表。 –

0

拆分表格不太可能有所幫助。同上PARTITIONing

讓我們來計算磁盤命中。我會跳過計算BTrees中的非葉節點;他們往往被緩存;我會統計數據和索引中的葉節點;他們往往不被緩存。

IODKU作用:

  1. 閱讀含有任何UNIQUE鍵索引塊。在你的情況下,這可能是user_id。請提供一個示例SQL語句。 1讀。
  2. 如果在索引中找到user_id條目,請從PK(id)索引的數據中讀取記錄,並執行UPDATE,並將第二個塊留在buffer_pool中,以便最終重寫到磁盤。 1現在閱讀,1後寫。
  3. 如果未找到記錄,請執行INSERT。需要新行的索引塊已被讀取,因此準備插入新條目。同時,表中的「最後」塊(由於idAUTO_INCREMENT)可能已被緩存。將新行添加到它。 0現在讀,1以後寫(UNIQUE)。 (重寫「最後一個」塊的時間是100行,所以我忽略它)。
  4. 最終進行寫操作。

總計,假設基本上全部採取UPDATE路徑:2次讀取和1次寫入。假設user_id不遵循任何簡單模式,我將假設所有3個I/O都是「隨機」的。

讓我們考慮一個變化...如果你擺脫了id?你需要id其他地方嗎?既然你有一個UNIQUE的鑰匙,可能是PK。這是用PRIMARY KEY(user_id)替換你的兩個索引。現在計數:

  1. 1讀
  2. 如果UPDATE,0讀,寫1
  3. 如果INSERT,0讀取,寫入0

總計:1次的讀,寫1。 2/3和以前一樣多。更好,但仍不是很好。

緩存

多少RAM你有?
innodb_buffer_pool_size的值是多少?
SHOW TABLE STATUS - 什麼是Data_lengthIndex_length

我懷疑buffer_pool不夠大,可能會引發。如果你有超過4GB的內存,使它大約佔內存的70%。

其他

因爲你似乎是I/O密集型

固態硬盤應該有顯著幫助。你能分辨出你是I/O綁定還是CPU綁定?

一次更新多少行?多久時間?它是批處理,還是一次一個?這裏可能會有重大改進。

您真的需要BIGINT(8字節)嗎? INT UNSIGNED只有4個字節。

是否涉及交易?

師父有問題嗎?奴隸?都?我不想以這樣的方式修理師父,弄亂奴隸。

+0

非常感謝。 我沒有考慮刪除自動遞增鍵。這太棒了。 1.我試圖改變innodb_buffer_pool_size的值,但沒有幫助。 2.我也嘗試了你的建議,使數據成批,這很好。 3.由於數據原因BIGINT無法更改。 4.並沒有事務involed。 5.只有主人有問題。 –

+0

完整的SQL是這樣的。 'INSERT DELAYED INTO mytable(user_id,identifier,account_id,top_speed,total_chars,total_time,keystrokes,avg_speed,country_code)VALUES(%s,%s,%s,%s,%s,%s,%s,%s, %s)ON DUPLICATE KEY UPDATE account_id =%s,top_speed =%s,total_chars =%s,total_time =%s,keystrokes =%s,avg_speed =%s「 –

+0

如果複製是」基於行「的,那麼一些磁盤命中只發生在Master中; Slave不需要在插入和更新之間重新決定,這可以解釋爲什麼只有Master有問題。 –