【MySQL進階學習】優化索引與分區表

優化索引

MySQL中,有兩種方式生成語序結果集,一種是使用file sort(慢查詢),一種是按索引順序掃描(要在經常排序的字段上建立索引)注意:不是索引越多越好!

爲索引列選擇合適的數據類型

  • 越小的數據類型通常更好:越小的數據類型通常在磁盤、內存和 CPU 緩存中都需要更少的空間,處理起來更快。
  • 簡單的數據類型更好:整型數據比起字符,處理開銷更小,因爲字符串的比較更復雜。IP的存儲問題。
  • 主鍵整型最好。
  • 避免 NULL,含有NULL的列做統計和查詢優化很麻煩。

一般原則

  1. 有大量重複值、經常進行範圍查詢(=、> 、 < 、> =、< =、between、in)和order bygroup by發生的列,可考慮建立聚簇索引。
  2. 經常同時存取多列,且每列都含有重複值可考慮建立組合索引,其前導列一定是使用最頻繁的列。
  3. 索引不會包含有 NULL 值的列。只要列中包含有NULL值都將不會被包含在索引中,複合索引中只要有一列含有 NULL值,那麼這一列對於此複合索引就是無效的。所以我們在數據庫設計時不要讓字段的默認值爲NULL
  4. 儘量使用短索引。對字符串列進行索引,如果可能應該指定一個前綴長度。
  5. 索引列排序。MySQL 查詢只使用一個索引,因此如果 where 子句中已經使用了索引的話,那麼 order by中的列是不會使用索引的。因此數據庫默認排序可以符合要求的情況下不要使用排序操作;儘量不要包含多個列的排序,如果需要最好給這些列創建複合索引。
  6. like 語句操作。一般情況下不鼓勵使用 like 操作,如果非使用不可,如何使用也是一個問題。like “%aaa%” 不會使用索引而 like “aaa%”可以使用索引。
  7. 儘量不要在列上進行運算。如,select * from users where YEAR(adddate)<2007,將在每個行上進行運算,這將導致索引失效而進行全表掃描,因此我們可以改成:select * from users where adddate<’2007-01-01′

建立索引,但是不走索引的情況

1.存在null值

select * 
from 
	表名 
where 
	字段名 is not null;

2.NOT條件
包括:<>、NOT、in、not exists

select * 
from 
	表名 
where 
	字段名 in (數值1,數值2,,,數值n);

3.LIKE通配符的後匹配

select *
from
    表名
where
    字段名 like '模糊搜索的條件';

4.函數運算

select * 
from 
	test 
where 
	//比如upper函數
	upper(name)='SUNYANG';

5.數據類型的轉換

select * 
from 
	sunyang 
where 
	id='123';

當查詢條件存在隱式轉換時,索引會失效。比如在數據庫裏id存的int類型,但是在查詢時,卻用了上面的形式,此舉例中id是int類型,但是輸入了字符類型。

6.複合索引前導列區分不大
參考如下:
MySQL執行計劃解讀

表分區

概念:表分區就是將一個大表按照mysql提供的幾種方式,分成幾個小表。
.
日常開發中我們經常會遇到大表的情況,所謂的大表是指存儲了百萬級乃至千萬級條記錄的表。這樣的表過於龐大,導致數據庫在查詢和插入的時候耗時太長、性能低下,如果涉及聯合查詢的情況,性能會更加糟糕。對錶進行分區,目的就是減少數據庫的負擔,提高數據庫的效率,通常來講就是提高表的增刪改查效率。
分區是將數據分段劃分在多個位置存放,可以是同一塊磁盤也可以在不同的機器。分區後,表面上還是一張表,但數據散列到多個位置了。應用程序讀寫的時候操作的還是大表名字,數據庫系統自動去組織分區的數據。

表分區的功能

  • 與單個磁盤或文件系統分區相比,可以存儲更多的數據。
  • 很容易就能刪除不用或者過時的數據。
  • 一些查詢可以得到極大的優化。
  • 涉及到 SUM()/COUNT() 等聚合函數時,可以並行進行。
  • IO 吞吐量更大。
  • 分區允許可以設置爲任意大小的規則,跨文件系統分配單個表的多個部分。實際上,表的不同部分在不同的位置被存儲爲單獨的表。

範圍分區(Range Partition

通常是使用頻率最高的分區,如按月份劃分,這樣的數據保持均勻性比較好,如果劃分的均勻性不是很好,需要考慮其他分區方法。
格式:

CREATE TABLE table_name(
	....//創建表的格式不變
)
partition by RANGE(table_column)(
	PARTITION p0 VALUES LESS THAN (values1),
	PARTITION p1 VALUES LESS THAN (values2),
	PARTITION p2 VALUES LESS THAN (values3)
	...
)

實例:可以將一個表通過年份劃分成兩個分區,2001-2010年、2011-2020。

列表分區(List Partition)

當需要明確控制如何將數據進行分區時,採用這種方式。只能進行單列分區,可以講數據進行分組,比如按城市分區,幾個城市放一起。
格式:

CREATE TABLE table_name(
	....//創建表不變
)
partition by LIST(table_column)(
	PARTITION p0 VALUES IN (0,4,8,12),
	PARTITION p1 VALUES IN (1,5,9,13), 
	PARTITION p2 VALUES IN (2,6,10,14), 
	PARTITION p3 VALUES IN (3,7,11,15)
	...
)

和範圍分區差不多,只不過一個是範圍,一個是具體數值。

哈希分區(Hash Partition)

如果數據不是那麼容易進行劃分,通過這種方式就很靈活了。可以將數據均勻的插入到不同的塊,在併發時有利於提高效率,當無法用Range分區時,就可以用Hash分區。
格式:

CREATE TABLE table_name(
	....//創建表不變
)
 PARTITION BY HASH(table_column) 
 PARTITIONS nums;

和上述兩種分表的格式不是太相同,只需要設置nums爲分區個數就行了,是一個整數值。

複合分區

未過多講述,如想了解,請移步–>全面總結Oracle中的分區表

參考筆記來自老師授課的教案:番茄發燒了

編程我也是初學者,難免有理解錯誤的地方,希望大家看完之後,發現錯誤可以評論出來,謝謝大家

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章