mysql单表索引个数_MySQL性能:多个表与单个表和分区上的索引
小編典典
創(chuàng)建20,000個(gè)表是一個(gè)壞主意。您很快將需要40,000個(gè)表,然后更多。
我在《SQL反模式》一書(shū)中將此綜合癥稱為
Metadata Tribbles
。您每次計(jì)劃創(chuàng)建“每X表格”或“每X列”時(shí)都會(huì)看到這種情況。
當(dāng)您有成千上萬(wàn)個(gè)表時(shí),這確實(shí)會(huì)導(dǎo)致實(shí)際的性能問(wèn)題。每個(gè)表都需要MySQL維護(hù)內(nèi)部數(shù)據(jù)結(jié)構(gòu),文件描述符,數(shù)據(jù)字典等。
還有實(shí)際的操作后果。您是否真的要?jiǎng)?chuàng)建一個(gè)系統(tǒng),該系統(tǒng)要求您每次注冊(cè)新用戶時(shí)都創(chuàng)建一個(gè)新表?
相反,我建議您使用MySQL分區(qū)。
這是對(duì)表進(jìn)行分區(qū)的示例:
CREATE TABLE statistics (
id INT AUTO_INCREMENT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY (id, user_id)
) PARTITION BY HASH(user_id) PARTITIONS 101;
這給您帶來(lái)了定義一個(gè)邏輯表的好處,同時(shí)還可以將該表分為許多物理表,以便在查詢分區(qū)鍵的特定值時(shí)可以更快地進(jìn)行訪問(wèn)。
例如,當(dāng)您像示例一樣運(yùn)行查詢時(shí),MySQL僅訪問(wèn)包含特定user_id的正確分區(qū):
mysql> EXPLAIN PARTITIONS SELECT * FROM statistics WHERE user_id = 1\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: statistics
partitions: p1
type: index
possible_keys: NULL
key: PRIMARY
key_len: 8
ref: NULL
rows: 2
Extra: Using where; Using index
分區(qū)的HASH方法意味著通過(guò)整數(shù)分區(qū)鍵的模數(shù)將行放置在分區(qū)中。這確實(shí)意味著許多user_id都映射到同一分區(qū),但是每個(gè)分區(qū)平均只有平均行數(shù)的1 /
N(其中N是分區(qū)數(shù))。而且您用固定數(shù)量的分區(qū)來(lái)定義表,因此不必在每次獲得新用戶時(shí)都對(duì)其進(jìn)行擴(kuò)展。
您可以選擇多達(dá)1024個(gè)分區(qū)(在MySQL 5.6中為8192)的任意數(shù)量的分區(qū),但是有些人報(bào)告說(shuō),當(dāng)分區(qū)過(guò)高時(shí)會(huì)出現(xiàn)性能問(wèn)題。
建議使用素?cái)?shù)分區(qū)。如果您的user_id值遵循某種模式(例如僅使用偶數(shù)),則使用質(zhì)數(shù)分區(qū)可以幫助更均勻地分配數(shù)據(jù)。
在評(píng)論中回答您的問(wèn)題:
如何確定合理的分區(qū)數(shù)量?
對(duì)于HASH分區(qū),如果您使用101個(gè)分區(qū)(如上例所示),則任何給定分區(qū)平均約占行的1%。您說(shuō)統(tǒng)計(jì)信息表有3000萬(wàn)行,因此,如果使用此分區(qū),則每個(gè)分區(qū)只有30萬(wàn)行。對(duì)于MySQL而言,這更容易閱讀。您也可以(也應(yīng)該)使用索引-
每個(gè)分區(qū)都有其自己的索引,并且其大小僅為整個(gè)未分區(qū)表的索引的1%。
因此,如何確定合理數(shù)量的分區(qū)的答案是:整個(gè)表有多大,并且您希望分區(qū)平均有多大?
分區(qū)數(shù)量不應(yīng)該隨著時(shí)間增長(zhǎng)嗎?如果是這樣:我該如何自動(dòng)化?
如果您使用HASH分區(qū),則分區(qū)的數(shù)量并不一定需要增加。最終,您可能總共有300億行,但是我發(fā)現(xiàn),當(dāng)您的數(shù)據(jù)量增長(zhǎng)幾個(gè)數(shù)量級(jí)時(shí),無(wú)論如何都需要一種新的體系結(jié)構(gòu)。如果您的數(shù)據(jù)變得如此之大,則可能需要在多個(gè)服務(wù)器上進(jìn)行
分片 以及將其分區(qū)到多個(gè)表中。
也就是說(shuō),您可以使用ALTER TABLE重新分區(qū)表:
ALTER TABLE statistics PARTITION BY HASH(user_id) PARTITIONS 401;
這必須重新組織表(就像大多數(shù)ALTER TABLE更改一樣),因此希望它花一些時(shí)間。
您可能要監(jiān)視分區(qū)中數(shù)據(jù)和索引的大小:
SELECT table_schema, table_name, table_rows, data_length, index_length
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE partition_method IS NOT NULL;
與任何表一樣,您希望活動(dòng)索引的總大小適合您的緩沖池,因?yàn)槿绻赟ELECT查詢期間MySQL必須在緩沖池中交換部分索引進(jìn)出索引,則性能會(huì)受到影響。
如果使用RANGE或LIST分區(qū),則添加,刪除,合并和拆分分區(qū)更為常見(jiàn)。見(jiàn)http://dev.mysql.com/doc/refman/5.6/en/partitioning-
management-range-
list.html
2020-05-17
總結(jié)
以上是生活随笔為你收集整理的mysql单表索引个数_MySQL性能:多个表与单个表和分区上的索引的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: mysql主从安装配置_如何安装和配置m
- 下一篇: mysql表级别的操作_MySql 库/