[英]MySQL I/O bound InnoDB query optimization problem without setting innodb_buffer_pool_size to 5GB
我陷入了MySQL設計可擴展性問題。 任何幫助將不勝感激。
要求:
存儲用戶在其社交圖中關於每個用戶的SOCIAL_GRAPH和USER_INFO。 每秒發生許多並發讀取和寫入。 臟讀是可以接受的。
當前設計:
我們有2個(相關)表。 兩種InnoDB都用於行鎖定,而不是表鎖定。
USER_SOCIAL_GRAPH表將已登錄的(user_id)映射到另一個(related_user_id)。 主鍵組合user_id和related_user_id。
USER_INFO表,其中包含有關每個相關用戶的信息。 主鍵為(related_user_id)。
注1:未定義關系。
注2:現在每個表的大小約為1GB,分別具有800萬條記錄和200萬條記錄。
簡化的表SQL創建:
CREATE TABLE `user_social_graph` (
`user_id` int(10) unsigned NOT NULL,
`related_user_id` int(11) NOT NULL,
PRIMARY KEY (`user_id`,`related_user_id`),
KEY `user_idx` (`user_id`)
) ENGINE=InnoDB;
CREATE TABLE `user_info` (
`related_user_id` int(10) unsigned NOT NULL,
`screen_name` varchar(20) CHARACTER SET latin1 DEFAULT NULL,
[... and many other non-indexed fields irrelevant]
`last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`related_user_id`),
KEY `last_updated_idx` (`last_updated`)
) ENGINE=InnoDB;
MY.CFG值設置為:
innodb_buffer_pool_size = 256M
key_buffer_size = 320M
注3:可用內存為1GB,這兩個表為2GB,其他innoDB表為3GB。
問題:
以下示例SQL語句需要訪問找到的所有記錄,需要15秒執行(!!),並且num_results = 220,000:
SELECT SQL_NO_CACHE COUNT(u.related_user_id)
FROM user_info u LEFT JOIN user_socialgraph u2 ON u.related_user_id = u2.related_user_id
WHERE u2.user_id = '1'
AND u.related_user_id = u2.related_user_id
AND (NOT (u.related_user_id IS NULL));
對於計數為30,000的user_id,大約需要3秒(!)。
對220,000個計數用戶的EXPLAIN EXTENDED。 它使用索引:
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
| 1 | SIMPLE | u2 | ref | user_user_idx,user_idx | user_idx | 4 | const | 157320 | 100.00 | Using where |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | u2.related_user_id | 1 | 100.00 | Using where; Using index |
+----+-------------+-------+--------+------------------------+----------+---------+--------------------+--------+----------+--------------------------+
如何在不將innodb_buffer_pool_size設置為5GB的情況下加快速度?
謝謝!
user_social_graph表未正確索引!!!
您有:
創建表user_social_graph
( user_id
int(10)unsigned NOT NULL,
related_user_id
int(11)NOT NULL,
主鍵( user_id
, related_user_id
),
密鑰user_idx
( user_id
))
ENGINE = InnoDB的;
由於第一列是user_id,因此第二個索引是冗余的。 您正在嘗試將related_user_id列加入到user_info表中。 該列需要索引。
如下更改user_social_graphs:
創建表user_social_graph
( user_id
int(10)unsigned NOT NULL,
related_user_id
int(11)NOT NULL,
主鍵( user_id
, related_user_id
),
唯一鍵related_user_idx
( related_user_id
, user_id
))
ENGINE = InnoDB的;
這應該更改“解釋計划”。 請記住,索引順序很重要,具體取決於查詢列的方式。
試試看 !!!
什么是MySQL版本? 它的手冊包含重要的信息,這些信息通常可以加快語句和代碼的速度。
將您的范例更改為能夠管理到TB級表的數據倉庫。 使用免費工具或應用程序將舊版MySQL數據庫遷移到新范例中。 這是一個示例: http : //www.infobright.org/Downloads/What-is-ICE/許多其他(免費和商業)。
PostgreSQL不是商業性的,有很多工具可以將MySQL遷移到它!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.