簡體   English   中英

mysql innodb內連接用longtext很慢

[英]mysql innodb inner join with longtext very slow

我上周將一個項目的所有MySQL表從MyISAM遷移到InnoDB,以支持交易。 為此,我使用了alter table的命令。

大多數工作正常,但是一個特定的查詢運行速度非常慢,它總是Incorrect key file for table '/tmp/#sql_xxxx_x.MYI提供錯誤Incorrect key file for table '/tmp/#sql_xxxx_x.MYI

后來我將問題縮小到2個表的內連接,即user表和agreement表。 而內部聯接采取的外鍵字段之間發生user (即agreement_id )和主鍵字段agreement (即id )。

user表只有50,000行數據, agreement表也​​有一行。 我們已經為用戶的agreement_id設置了索引。

無論如何,這似乎是一個非常輕量級的查詢,但事實證明它是整個瓶頸。

這是完整的agreement架構:

CREATE TABLE IF NOT EXISTS `agreement` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `remark` varchar(200) NOT NULL,
  `content` longtext NOT NULL,
  `is_active` tinyint(1) NOT NULL,
  `date_stamp` datetime NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8 AUTO_INCREMENT=2 ;

我懷疑的一件事是agreement表中的remark的longtext字段,但我們沒有使用該字段進行內連接,實際上即使我們沒有在查詢結果中選擇remark ,查詢也很慢。

最后,我們將agreement表從innoDBMyISAM ,而不是一切正常。 查詢在不到1秒的時間內完成。

現在,我的問題是這里究竟發生了什么? 這是否意味着一旦innoDB表包含任何文本字段,那么該表不能用於內連接?

我希望我能夠知道真正的原因,以便我將來可以避免同樣的問題。

非常感謝。

這是一個着名而棘手的問題。 最可能的原因是你在/ tmp中沒有空間。

這是我在書簽中保留的鏈接,可以幫助您: http//www.mysqlperformancetuning.com/a-fix-for-incorrect-key-file-for-table-mysql

根據我的經驗,盡管有限,但看到此錯誤消息的主要原因是因為您的tmpdir空間不足。 像我一樣,你會檢查你有多少可用空間:1Gb,2Gb,4Gb。 這可能還不夠。 這就是原因:MySQL可以在幾秒鍾內創建比這更大的臨時表,快速填滿任何可用空間。 具體取決於查詢的性質和數據庫的大小。

您也可以嘗試在桌面上使用REPAIR ,但對我而言,它與breakdancing一樣有用:/

InnoDB有自己的緩沖區大小等設置。檢查出來,如果你可以調整它,繼續。 只是為了測試嘗試加倍,如果它有幫助,你可能想要優化它。 它可以產生很大的不同。

一些可能有用的鏈接:

http://www.mysqlperformanceblog.com/2007/11/03/choosing-innodb_buffer_pool_size/

http://dev.mysql.com/doc/refman/5.5/en/innodb-buffer-pool.html

也許這里的問題是remark字段定義為varchar(200) 請記住,臨時表和內存表存儲具有固定長度的varchar 所以帶有varchar(200) 50k行即使它們都是空的,也會占用大量內存。

如果這是問題,那么你可以嘗試以下幾種方法之一:

您的查詢的目的是什么? 我從您的評論中看到,您只列出了用戶信息,而且協議中沒有任何內容讓我相信您正在尋找有協議的用戶? 由於您在引擎之間進行轉換,因此我會在添加約束之前認為您正在進行清理。 如果是這樣,請考慮使用用戶表中的左連接,如:

select user.* from user left join agreement on user.agreement_id = agreement.id where user.agreement_id != 0;

如果它不是清理,而只是尋找具有協議的用戶,我們就會變得簡單

select user.* from user where user.agreement_id != 0;

如果目的不是其他,請考慮在user.agreement_id上添加索引,因為內部聯接可能需要它來提高速度。 讓我們知道真正的目的,你可能會得到更好的幫助。

暫無
暫無

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

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