mariadb 分割槽表 不能使用 ICP
來源:SQL開發與最佳化
其中有如下文章:
現有一個SQL 假設 剛開始沒有 KEY `idx_de3` (`dept_no`,`from_date`) 這個索引
select *
count(to_date) from dept_emp5 s force index(idx_de3_n1)
where s.dept_no = t.dept_no and from_date >='1900-01-03'
and from_date <= '1985-01-01') s from t_group t \G
1. row ***************************
id: 1
select_type: PRIMARY
table: t
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 10
Extra:
2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: s
type: ref
possible_keys: idx_de3_n1
key: idx_de3_n1
key_len: 19
ref: employees.t.dept_no
rows: 164667
Extra: Using index condition; Using where
2 rows in set (0.000 sec)
這裡 Using index condition; Using where
其實已經用了ICP ,這是我在重現過程中的不嚴謹導致的。
但是實際最佳化的資料庫只有using where 而沒有 Using index condition;
如果使用了 ICP 那就沒有後面的一堆事情了 。
Connection id: 81
Current database: employees
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server: MariaDB
Server version: 10.6.8-MariaDB-log MariaDB Server
Protocol version: 10
生產庫版本是10.4.22 我在10.6.8 裡也重現
root@maria3310.sock>[employees]>show create table emp31\G
*************************** 1. row ***************************
Table: emp31
Create Table: CREATE TABLE `emp31` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
`n1` varchar(10) DEFAULT NULL,
`n2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`emp_no`,`birth_date`),
KEY `idx_emp3_n1` (`first_name`,`birth_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.000 sec)
root@maria3310.sock>[employees]>show create table emp3\G
*************************** 1. row ***************************
Table: emp3
Create Table: CREATE TABLE `emp3` (
`emp_no` int(11) NOT NULL,
`birth_date` date NOT NULL,
`first_name` varchar(14) NOT NULL,
`last_name` varchar(16) NOT NULL,
`gender` enum('M','F') NOT NULL,
`hire_date` date NOT NULL,
`n1` varchar(10) DEFAULT NULL,
`n2` varchar(10) DEFAULT NULL,
PRIMARY KEY (`emp_no`,`birth_date`),
KEY `idx_emp3_n1` (`first_name`,`birth_date`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
PARTITION BY RANGE (to_days(`birth_date`))
(PARTITION `p202102` VALUES LESS THAN (738215) ENGINE = InnoDB,
PARTITION `p202103` VALUES LESS THAN (738246) ENGINE = InnoDB,
PARTITION `p202104` VALUES LESS THAN (738276) ENGINE = InnoDB,
PARTITION `p202105` VALUES LESS THAN (738307) ENGINE = InnoDB,
PARTITION `p202106` VALUES LESS THAN (738337) ENGINE = InnoDB,
PARTITION `p202107` VALUES LESS THAN (738368) ENGINE = InnoDB,
PARTITION `p202108` VALUES LESS THAN (738399) ENGINE = InnoDB,
PARTITION `p202109` VALUES LESS THAN (738429) ENGINE = InnoDB,
PARTITION `pmax` VALUES LESS THAN MAXVALUE ENGINE = InnoDB)
1 row in set (0.000 sec)
我建立瞭如上兩個表一個是分割槽表 emp3,一個非分割槽表emp31
root@maria3310.sock>[employees]>desc select * from emp3 where first_name='Chirstian' and birth_date like '1954%'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp3
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: const
rows: 9
Extra: Using where
1 row in set (0.001 sec)
root@maria3310.sock>[employees]>desc select * from emp31 where first_name='Chirstian' and birth_date like '1954%'\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: emp31
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: const
rows: 1
Extra: Using index condition
1 row in set (0.000 sec)
如上所示,非分割槽表是有 Extra: Using index condition 而分割槽表沒有!!
root@maria3310.sock>[employees]>desc select t.* ,(select e.hire_date from emp3 e where e.first_name = t.first_name and birth_date like '1954%' limit 1 ) c from emp31 t limit 10 \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1000
Extra:
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: e
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: employees.t.first_name
rows: 1
Extra: Using where
2 rows in set (0.001 sec)
root@maria3310.sock>[employees]>desc select t.* ,(select e.hire_date from emp31 e where e.first_name = t.first_name and birth_date like '1954%' limit 1 ) c from emp3 t limit 10 \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1008
Extra:
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: e
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: employees.t.first_name
rows: 1
Extra: Using index condition
2 rows in set (0.000 sec)
我們在用子查詢驗證下,還是重現了非分割槽表不能使用ICP 這個特性
Server version: 8.0.31 MySQL Community Server - GPL
Protocol version: 10
root@mysql3306.sock>[employees]>desc select t.* ,(select e.hire_date from emp3 e where e.first_name = t.first_name and birth_date like '1954%' limit 1 ) c from emp31 t limit 10 \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t
partitions: NULL
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1000
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: e
partitions: p202102,p202103,p202104,p202105,p202106,p202107,p202108,p202109,pmax
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: employees.t.first_name
rows: 1
filtered: 11.11
Extra: Using index condition
2 rows in set, 2 warnings (0.00 sec)
root@mysql3306.sock>[employees]>desc select t.* ,(select e.hire_date from emp31 e where e.first_name = t.first_name and birth_date like '1954%' limit 1 ) c from emp3 t limit 10 \G
*************************** 1. row ***************************
id: 1
select_type: PRIMARY
table: t
partitions: p202102,p202103,p202104,p202105,p202106,p202107,p202108,p202109,pmax
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 1000
filtered: 100.00
Extra: NULL
*************************** 2. row ***************************
id: 2
select_type: DEPENDENT SUBQUERY
table: e
partitions: NULL
type: ref
possible_keys: idx_emp3_n1
key: idx_emp3_n1
key_len: 58
ref: employees.t.first_name
rows: 1
filtered: 11.11
Extra: Using index condition
2 rows in set, 2 warnings (0.00 sec)
我又在
5.7.36-log MySQL Community Server (GPL)
下面的版本里做了實驗,還是可以使用ICP
MySQL 還是非常好用!!
這樣經過昨天和今天的文章,總算把這個問題搞懂了。
根本原因是分割槽表不能使用ICP 為了想辦法繞過這個問題
我用了等號方式和函式方式,在函式方式的時候又踩了一個引數的坑!
最終經過一系列操作之後總算回到了正確的路上。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027826/viewspace-2984931/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- oracle分割槽表和分割槽表exchangeOracle
- oracle分割槽表和非分割槽表exchangeOracle
- PostgreSQL/LightDB 分割槽表之分割槽裁剪SQL
- PG的非分割槽表線上轉分割槽表
- (3) MySQL分割槽表使用方法MySql
- 教程:如何使用DataLakeAnalytics建立分割槽表
- 【MYSQL】 分割槽表MySql
- PostgreSQL使用表繼承實現分割槽表SQL繼承
- 非分割槽錶轉換成分割槽表
- [oracle] expdp 匯出分割槽表的分割槽Oracle
- Oracle分割槽表基礎運維-07增加分割槽(3列表分割槽)Oracle運維
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- 移動分割槽表和分割槽索引的表空間索引
- Oracle分割槽表基礎運維-04列表分割槽Oracle運維
- 如何使用Data Lake Analytics建立分割槽表
- Oracle分割槽表基礎運維-07增加分割槽(2 HASH分割槽)Oracle運維
- 分割槽表-實戰
- MySQL 分割槽表探索MySql
- Oracle分割槽表基礎運維-06分割槽表索引Oracle運維索引
- 【Linux】MBR磁碟分割槽表只能有四個分割槽?Linux
- oracle 線上重新定義,普通表改變分割槽表,分割槽表可以更改型別、分割槽欄位等Oracle型別
- Oracle分割槽表基礎運維-07增加分割槽(1範圍分割槽)Oracle運維
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維
- Oracle分割槽表基礎運維-09刪除分割槽Oracle運維
- Oracle分割槽表基礎運維-05組合分割槽Oracle運維
- Oracle分割槽表基礎運維-02範圍分割槽Oracle運維
- Oracle分割槽表基礎運維-03HASH分割槽Oracle運維
- 分割槽表之自動增加分割槽(11G)
- Mysql表分割槽實操MySql
- OceaBase 分割槽表建立技巧
- Mysql表分割槽實現MySql
- PostgreSQL:傳統分割槽表SQL
- PostgreSQL:內建分割槽表SQL
- SQL SERVER之分割槽表SQLServer
- ORACLE分割槽表梳理系列Oracle
- Spark操作Hive分割槽表SparkHive
- mysql 進行表分割槽MySql
- oracle將表配置為分割槽表Oracle