好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > MySQL 8.0統計信息不準確的原因

MySQL 8.0統計信息不準確的原因

熱門標簽:申請400電話電話價格 石家莊400電話辦理公司 地圖標注客戶付款 宜賓全自動外呼系統廠家 許昌外呼增值業務線路 臨沂做地圖標注 咸陽防封電銷卡 新鄉智能外呼系統好處 廣東400企業電話申請流程

前言

不管是Oracle還是MySQL,新版本推出的新特性,一方面給產品帶來功能、性能、用戶體驗等方面的提升,另一方面也可能會帶來一些問題,如代碼bug、客戶使用方法不正確引發問題等等。

案例分享

MySQL 5.7下的場景

(1)首先,創建兩張表,并插入數據

mysql> select version();
+------------+
| version() |
+------------+
| 5.7.30-log |
+------------+
1 row in set (0.00 sec)

mysql> show create table test\G
*************************** 1. row ***************************
    Table: test
Create Table: CREATE TABLE `test` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `k` int(10) unsigned NOT NULL DEFAULT '0',
 `c` char(120) NOT NULL DEFAULT '',
 `pad` char(60) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`),
 KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 MAX_ROWS=1000000
1 row in set (0.00 sec)

mysql> show create table sbtest1\G
*************************** 1. row ***************************
    Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
 `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `k` int(10) unsigned NOT NULL DEFAULT '0',
 `c` char(120) NOT NULL DEFAULT '',
 `pad` char(60) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`),
 KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 MAX_ROWS=1000000
1 row in set (0.00 sec)

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|   100 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.14 sec)

(2)查看兩張表的統計信息,均比較準確

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| table_schema | table_name | table_rows |
+--------------+------------+------------+
| test     | test    |    100 |
+--------------+------------+------------+
1 row in set (0.00 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='sbtest1';
+--------------+------------+------------+
| table_schema | table_name | table_rows |
+--------------+------------+------------+
| test     | sbtest1  |   947263 |
+--------------+------------+------------+
1 row in set (0.00 sec)

(3)我們持續往test表插入1000w條記錄,并再次查看統計信息,還是相對準確的,因為在默認情況下,數據變化量超過10%,就會觸發統計信息更新

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 10000100 |
+----------+
1 row in set (1.50 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| table_schema | table_name | table_rows |
+--------------+------------+------------+
| test     | test    |  9749036 |
+--------------+------------+------------+
1 row in set (0.00 sec)

MySQL 8.0下的場景

(1)接下來我們看看8.0下的情況吧,同樣地,我們創建兩張表,并插入相同記錄

mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.20  |
+-----------+
1 row in set (0.00 sec)

mysql> show create table test\G
*************************** 1. row ***************************
    Table: test
Create Table: CREATE TABLE `test` (
 `id` int unsigned NOT NULL AUTO_INCREMENT,
 `k` int unsigned NOT NULL DEFAULT '0',
 `c` char(120) NOT NULL DEFAULT '',
 `pad` char(60) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`),
 KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=101 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci MAX_ROWS=1000000
1 row in set (0.00 sec)

mysql> show create table sbtest1\G
*************************** 1. row ***************************
    Table: sbtest1
Create Table: CREATE TABLE `sbtest1` (
 `id` int unsigned NOT NULL AUTO_INCREMENT,
 `k` int unsigned NOT NULL DEFAULT '0',
 `c` char(120) NOT NULL DEFAULT '',
 `pad` char(60) NOT NULL DEFAULT '',
 PRIMARY KEY (`id`),
 KEY `k_1` (`k`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci MAX_ROWS=1000000
1 row in set (0.00 sec)

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|   100 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.02 sec)

(2)查看兩張表的統計信息,均比較準確

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | test    |    100 |
+--------------+------------+------------+
1 row in set (0.00 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='sbtest1';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | sbtest1  |   947468 |
+--------------+------------+------------+
1 row in set (0.01 sec)

(3)同樣地,我們持續往test表插入1000w條記錄,并再次查看統計信息,發現table_rows顯示還是100條,出現了較大偏差

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 10000100 |
+----------+
1 row in set (0.33 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | test    |    100 |
+--------------+------------+------------+
1 row in set (0.00 sec)

原因剖析

那么導致統計信息不準確的原因是什么呢?其實是MySQL 8.0為了提高information_schema的查詢效率,將視圖tables和statistics里面的統計信息緩存起來,緩存過期時間由參數information_schema_stats_expiry決定,默認為86400s;如果想獲取最新的統計信息,可以通過如下兩種方式:

(1)analyze table進行表分析

(2)設置information_schema_stats_expiry=0

繼續探索

那么統計信息不準確,會帶來哪些影響呢?是否會影響執行計劃呢?接下來我們再次進行測試

測試1:表test記錄數100,表sbtest1記錄數100w

執行如下SQL,查看執行計劃,走的是NLJ,小表test作為驅動表(全表掃描),大表sbtest1作為被驅動表(主鍵關聯),執行效率很快

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
|   100 |
+----------+
1 row in set (0.00 sec)

mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.02 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | test    |    100 |
+--------------+------------+------------+
1 row in set (0.00 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='sbtest1';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | sbtest1  |   947468 |
+--------------+------------+------------+
1 row in set (0.01 sec)

mysql> select t.* from test t inner join sbtest1 t1 on t.id=t1.id where t.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' and t1.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977';
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k   | c                                                            | pad                             |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 1 | 501885 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> explain select t.* from test t inner join sbtest1 t1 on t.id=t1.id where t.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' and t1.c='08566691963-88624912351-16662227201-4664
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key   | key_len | ref    | rows | filtered | Extra    |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
| 1 | SIMPLE   | t   | NULL    | ALL  | PRIMARY    | NULL  | NULL  | NULL   | 100 |  10.00 | Using where |
| 1 | SIMPLE   | t1  | NULL    | eq_ref | PRIMARY    | PRIMARY | 4    | test.t.id |  1 |  10.00 | Using where |
+----+-------------+-------+------------+--------+---------------+---------+---------+-----------+------+----------+-------------+
2 rows in set, 1 warning (0.00 sec)

測試2:表test記錄數1000w左右,表sbtest1記錄數100w

再次執行SQL,查看執行計劃,走的也是NLJ,相對小表sbtest1作為驅動表,大表test作為被驅動表,也是正確的執行計劃

mysql> select count(*) from test;
+----------+
| count(*) |
+----------+
| 10000100 |
+----------+
1 row in set (0.33 sec)

mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 1000000 |
+----------+
1 row in set (0.02 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='test';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | test    |    100 |
+--------------+------------+------------+
1 row in set (0.00 sec)

mysql> select table_schema,table_name,table_rows from tables where table_name='sbtest1';
+--------------+------------+------------+
| TABLE_SCHEMA | TABLE_NAME | TABLE_ROWS |
+--------------+------------+------------+
| test     | sbtest1  |   947468 |
+--------------+------------+------------+
1 row in set (0.01 sec)

mysql> select t.* from test t inner join sbtest1 t1 on t.id=t1.id where t.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' and t1.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977';
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k   | c                                                            | pad                             |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 1 | 501885 | 08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977 | 63188288836-92351140030-06390587585-66802097351-49282961843 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.37 sec)

mysql> explain select t.* from test t inner join sbtest1 t1 on t.id=t1.id where t.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977' and t1.c='08566691963-88624912351-16662227201-46648573979-64646226163-77505759394-75470094713-41097360717-15161106334-50535565977';
+----+-------------+-------+------------+--------+---------------+---------+---------+------------+--------+----------+-------------+
| id | select_type | table | partitions | type  | possible_keys | key   | key_len | ref    | rows  | filtered | Extra    |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------+--------+----------+-------------+
| 1 | SIMPLE   | t1  | NULL    | ALL  | PRIMARY    | NULL  | NULL  | NULL    | 947468 |  10.00 | Using where |
| 1 | SIMPLE   | t   | NULL    | eq_ref | PRIMARY    | PRIMARY | 4    | test.t1.id |   1 |  10.00 | Using where |
+----+-------------+-------+------------+--------+---------------+---------+---------+------------+--------+----------+-------------+
2 rows in set, 1 warning (0.01 sec)

為什么優化器沒有選擇錯誤的執行計劃呢?之前文章也提過,MySQL 8.0是將元數據信息存放在mysql庫下的數據字典表里,information_schema庫只是提供相對方便的視圖供用戶查詢,所以優化器在選擇執行計劃時,會從數據字典表中獲取統計信息,生成正確的執行計劃。

總結

MySQL 8.0為了提高information_schema的查詢效率,會將視圖tables和statistics里面的統計信息緩存起來,緩存過期時間由參數information_schema_stats_expiry決定(建議設置該參數值為0);這可能會導致用戶查詢相應視圖時,無法獲取最新、準確的統計信息,但并不會影響執行計劃的選擇。

以上就是MySQL 8.0統計信息不準確的原因的詳細內容,更多關于MySQL 8.0統計信息不準確的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • gearman + mysql方式實現持久化操作示例
  • 詳解使用Docker部署MySQL(數據持久化)
  • Java emoji持久化mysql過程詳解
  • MySQL8新特性:持久化全局變量的修改方法
  • MySQL8新特性:自增主鍵的持久化詳解
  • 概述MySQL統計信息
  • 詳解mysql持久化統計信息

標簽:日照 合肥 北京 阜新 鎮江 臺灣 鷹潭 貴州

巨人網絡通訊聲明:本文標題《MySQL 8.0統計信息不準確的原因》,本文關鍵詞  MySQL,8.0,統計,信息,不準確,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《MySQL 8.0統計信息不準確的原因》相關的同類信息!
  • 本頁收集關于MySQL 8.0統計信息不準確的原因的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 免费 人Av在线影院日本| 大草莓app| 日韩精品无码视频一区二区三区| 国产亚洲精品久久久久婷婷瑜伽| 91啦porny| 做运动打扑克视频软件下载| 杨门女将肉艳片在线观看| 蝌蚪视频国产成人无码免费| 久久99国产这里有精品视| 67194老司机精品午夜| 一级特黄aaa大片在线观看视频| 女人被添荫蒂舒服了的更新时间| 国产精品无码亚洲欧美在线网址| 国产永久免费裸体美女视频| 男女考比视频| 吉泽三步被躁57分钟在线播放| 麻豆精产国品一二三区发展历程 | 粗大与亲女伦交换H文| 九.幺成人小视频免费版下载| 艹bapp| 寡妇女教师bd高清在线观看| 18av视频| 婷婷五月六月丁香| 阴痉插入阴道视频| 特级黄国产片一级视频播放| 模特套圖私拍HDXXXX| 黄色天堂在线| 国产v综合v亚洲欧美冫| 男人使劲躁女人过程视频| 8x8国产人妻精品一区二区| 欧美很很干| 国产国产成年年人手机| 女人被躁到高潮免费视频网站95| 77777少妇AAAAA片毛片 | chinesegay精牛videos| 蹭蹭嗯啊h女女互慰女h| 午夜无码人妻AV大片| 鲁丝AV鲁丝一鲁丝二鲁丝三 | 国产野战农村妇女一级A片小说 | japanese丰满成熟mature | 久久久婷婷综合国自产拍揄泬 |