最近困擾自己很久的膝蓋積液手術終於做完,在家養傷,逛技術博客看到easyswoole開發組成員仙士可博客有關mysql索引方面的知識,自己打算重溫下。 正常業務起步數據表數據量較少,不用考慮使用索引,當後期累積的數據數量非常可觀時,使用索引是提升查詢的一條途徑,其他的像表分區,分庫分表等等。 【索引 ...
最近困擾自己很久的膝蓋積液手術終於做完,在家養傷,逛技術博客看到easyswoole開發組成員仙士可博客有關mysql索引方面的知識,自己打算重溫下。
正常業務起步數據表數據量較少,不用考慮使用索引,當後期累積的數據數量非常可觀時,使用索引是提升查詢的一條途徑,其他的像表分區,分庫分表等等。
【索引創建】
索引的創建需要考慮被創建索引的欄位區分度,比如一張表裡面有渠道channel,渠道可期種類不超過3種,win系,安卓系,iOS系,而數據表數據量有一百萬,平均下來每個渠道各是1/3也就是33萬數據,這樣的數據量就是否基於channel 索引區別都不會太大。
但是如果基於date欄位做索引,如20200114,一年一百萬,除以365天,平均下來每天300條數據。這個區分度是相當大。
同樣的索引使用 33w數據查詢顯然效率低於300條數據。
索引可以加快mysql服務查詢速度,但不是索引越多越好,因為數據insert或update的時候,存放索引的文件同樣需要進行更新,這裡會拖慢數據插入更新的速度,如果對數據實時性有要求的,無疑會受影響。
【索引使用】
組合索引:組合索引是有多個欄位聯合查詢使用的索引,遵循從左到右依次匹配的原則
【索引失效】
sql拼寫欄位不是依照組合索引從左至右原則;
索引欄位是字元串類型,sql拼接使用整型。如下:
MySQL [test_db]> show create table test_users\G; *************************** 1. row *************************** Table: test_users Create Table: CREATE TABLE `test_users` ( `uid` int(11) unsigned NOT NULL AUTO_INCREMENT, `username` char(15) NOT NULL, `created_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `user_id` char(11) NOT NULL DEFAULT '0', PRIMARY KEY (`uid`), KEY `testindex` (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1306001 DEFAULT CHARSET=utf8mb4 1 row in set (0.04 sec)
MySQL [test_db]> explain select * from test_users where user_id ='1273656';
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
| 1 | SIMPLE | test_users | NULL | ref | testindex | testindex | 44 | const | 1 | 100.00 | NULL |
+----+-------------+------------+------------+------+---------------+-----------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.05 sec)
MySQL [test_db]> explain select * from test_users where user_id =1273656;
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
| 1 | SIMPLE | test_users | NULL | ALL | testindex | NULL | NULL | NULL | 306078 | 10.00 | Using where |
+----+-------------+------------+------------+------+---------------+------+---------+------+--------+----------+-------------+
1 row in set, 3 warnings (0.04 sec)
可以發現第一條sql的 type = ref,key = testindex,第二條sql的 type = ALL,key = null也就是沒用到任何索引而是全表掃描
未完待續...