information_schema 数据库相当于一个数据字典,保存了表的元信息。

    1. mysql> use information_schema;
    2. Reading table information for completion of table and column names
    3. You can turn off this feature to get a quicker startup with -A
    4. Database changed
    5. mysql> show tables;
    6. +---------------------------------------+
    7. | Tables_in_information_schema |
    8. +---------------------------------------+
    9. | CHARACTER_SETS |
    10. | COLLATIONS |
    11. | COLLATION_CHARACTER_SET_APPLICABILITY |
    12. | COLUMNS |
    13. | COLUMN_PRIVILEGES |
    14. | ENGINES |
    15. | EVENTS |
    16. | FILES |
    17. | GLOBAL_STATUS |
    18. | GLOBAL_VARIABLES |
    19. | KEY_COLUMN_USAGE |
    20. | OPTIMIZER_TRACE |
    21. | PARAMETERS |
    22. | PARTITIONS |
    23. | PLUGINS |
    24. | PROCESSLIST |
    25. | PROFILING |
    26. | REFERENTIAL_CONSTRAINTS |
    27. | ROUTINES |
    28. | SCHEMATA |
    29. | SCHEMA_PRIVILEGES |
    30. | SESSION_STATUS |
    31. | SESSION_VARIABLES |
    32. | STATISTICS |
    33. | TABLES |
    34. | TABLESPACES |
    35. | TABLE_CONSTRAINTS |
    36. | TABLE_PRIVILEGES |
    37. | TRIGGERS |
    38. | USER_PRIVILEGES |
    39. | VIEWS |
    40. | INNODB_LOCKS |
    41. | INNODB_TRX |
    42. | INNODB_SYS_DATAFILES |
    43. | INNODB_FT_CONFIG |
    44. | INNODB_SYS_VIRTUAL |
    45. | INNODB_CMP |
    46. | INNODB_FT_BEING_DELETED |
    47. | INNODB_CMP_RESET |
    48. | INNODB_CMP_PER_INDEX |
    49. | INNODB_CMPMEM_RESET |
    50. | INNODB_FT_DELETED |
    51. | INNODB_BUFFER_PAGE_LRU |
    52. | INNODB_LOCK_WAITS |
    53. | INNODB_TEMP_TABLE_INFO |
    54. | INNODB_SYS_INDEXES |
    55. | INNODB_SYS_TABLES |
    56. | INNODB_SYS_FIELDS |
    57. | INNODB_CMP_PER_INDEX_RESET |
    58. | INNODB_BUFFER_PAGE |
    59. | INNODB_FT_DEFAULT_STOPWORD |
    60. | INNODB_FT_INDEX_TABLE |
    61. | INNODB_FT_INDEX_CACHE |
    62. | INNODB_SYS_TABLESPACES |
    63. | INNODB_METRICS |
    64. | INNODB_SYS_FOREIGN_COLS |
    65. | INNODB_CMPMEM |
    66. | INNODB_BUFFER_POOL_STATS |
    67. | INNODB_SYS_COLUMNS |
    68. | INNODB_SYS_FOREIGN |
    69. | INNODB_SYS_TABLESTATS |
    70. +---------------------------------------+
    71. 61 rows in set (0.00 sec)

    查看索引信息。

    1. mysql> select * from key_column_usage limit 3\G -- 显示了哪个索引使用了哪个列
    2. *************************** 1. row ***************************
    3. CONSTRAINT_CATALOG: def
    4. CONSTRAINT_SCHEMA: burn_test
    5. CONSTRAINT_NAME: PRIMARY
    6. TABLE_CATALOG: def
    7. TABLE_SCHEMA: burn_test
    8. TABLE_NAME: Orders -- 表名
    9. COLUMN_NAME: order_id -- 索引的名称
    10. ORDINAL_POSITION: 1
    11. POSITION_IN_UNIQUE_CONSTRAINT: NULL
    12. REFERENCED_TABLE_SCHEMA: NULL
    13. REFERENCED_TABLE_NAME: NULL
    14. REFERENCED_COLUMN_NAME: NULL
    15. *************************** 2. row ***************************
    16. CONSTRAINT_CATALOG: def
    17. CONSTRAINT_SCHEMA: burn_test
    18. CONSTRAINT_NAME: product_name
    19. TABLE_CATALOG: def
    20. TABLE_SCHEMA: burn_test
    21. TABLE_NAME: Orders_MV
    22. COLUMN_NAME: product_name
    23. ORDINAL_POSITION: 1
    24. POSITION_IN_UNIQUE_CONSTRAINT: NULL
    25. REFERENCED_TABLE_SCHEMA: NULL
    26. REFERENCED_TABLE_NAME: NULL
    27. REFERENCED_COLUMN_NAME: NULL
    28. *************************** 3. row ***************************
    29. CONSTRAINT_CATALOG: def
    30. CONSTRAINT_SCHEMA: burn_test
    31. CONSTRAINT_NAME: child_ibfk_1
    32. TABLE_CATALOG: def
    33. TABLE_SCHEMA: burn_test
    34. TABLE_NAME: child
    35. COLUMN_NAME: parent_id
    36. ORDINAL_POSITION: 1
    37. POSITION_IN_UNIQUE_CONSTRAINT: 1
    38. REFERENCED_TABLE_SCHEMA: burn_test
    39. REFERENCED_TABLE_NAME: parent
    40. REFERENCED_COLUMN_NAME: id
    41. 3 rows in set (0.04 sec)

    可以通过 STATISTICS 表的数据信息,分析索引的 Cardinality 数据。

    1. --
    2. -- information_schema.STATISTICS 中记录了相关的信息
    3. --
    4. mysql> use information_schema;
    5. Database changed
    6. mysql> show create table STATISTICS\G
    7. *************************** 1. row ***************************
    8. Table: STATISTICS
    9. Create Table: CREATE TEMPORARY TABLE `STATISTICS` (
    10. `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
    11. `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '', -- 表所在的库
    12. `TABLE_NAME` varchar(64) NOT NULL DEFAULT '', -- 表名
    13. `NON_UNIQUE` bigint(1) NOT NULL DEFAULT '0',
    14. `INDEX_SCHEMA` varchar(64) NOT NULL DEFAULT '',
    15. `INDEX_NAME` varchar(64) NOT NULL DEFAULT '', -- 索引名
    16. `SEQ_IN_INDEX` bigint(2) NOT NULL DEFAULT '0', -- 索引的序号
    17. `COLUMN_NAME` varchar(64) NOT NULL DEFAULT '',
    18. `COLLATION` varchar(1) DEFAULT NULL,
    19. `CARDINALITY` bigint(21) DEFAULT NULL, -- 这里我们找到了Cardinality
    20. `SUB_PART` bigint(3) DEFAULT NULL,
    21. `PACKED` varchar(10) DEFAULT NULL,
    22. `NULLABLE` varchar(3) NOT NULL DEFAULT '',
    23. `INDEX_TYPE` varchar(16) NOT NULL DEFAULT '',
    24. `COMMENT` varchar(16) DEFAULT NULL,
    25. `INDEX_COMMENT` varchar(1024) NOT NULL DEFAULT ''
    26. ) ENGINE=MEMORY DEFAULT CHARSET=utf8
    27. 1 row in set (0.00 sec)

    比如我们查看 employees.salaries 表中的索引信息:

    1. --
    2. -- 之前我们可以通过 show index from table_name的方式查看索引
    3. --
    4. mysql> show index from employees.salaries\G
    5. *************************** 1. row ***************************
    6. Table: salaries
    7. Non_unique: 0
    8. Key_name: PRIMARY
    9. Seq_in_index: 1 -- 索引序号为1
    10. Column_name: emp_no
    11. Collation: A
    12. Cardinality: 286271 -- Cardinality
    13. Sub_part: NULL
    14. Packed: NULL
    15. Null:
    16. Index_type: BTREE
    17. Comment:
    18. Index_comment:
    19. *************************** 2. row ***************************
    20. Table: salaries
    21. Non_unique: 0
    22. Key_name: PRIMARY
    23. Seq_in_index: 2 -- 索引序号为2
    24. Column_name: from_date
    25. Collation: A
    26. Cardinality: 2760952 -- Cardinality
    27. Sub_part: NULL
    28. Packed: NULL
    29. Null:
    30. Index_type: BTREE
    31. Comment:
    32. Index_comment:
    33. 2 rows in set (0.00 sec)
    34. --
    35. -- 现在可以通过STATISTICS表查看某张表的信息
    36. --
    37. mysql> select * from STATISTICS where table_name='salaries'\G
    38. *************************** 1. row ***************************
    39. TABLE_CATALOG: def
    40. TABLE_SCHEMA: employees
    41. TABLE_NAME: salaries
    42. NON_UNIQUE: 0
    43. INDEX_SCHEMA: employees
    44. INDEX_NAME: PRIMARY
    45. SEQ_IN_INDEX: 1 -- 索引序号为1
    46. COLUMN_NAME: emp_no
    47. COLLATION: A
    48. CARDINALITY: 286271 -- Cardinality
    49. SUB_PART: NULL
    50. PACKED: NULL
    51. NULLABLE:
    52. INDEX_TYPE: BTREE
    53. COMMENT:
    54. INDEX_COMMENT:
    55. *************************** 2. row ***************************
    56. TABLE_CATALOG: def
    57. TABLE_SCHEMA: employees
    58. TABLE_NAME: salaries
    59. NON_UNIQUE: 0
    60. INDEX_SCHEMA: employees
    61. INDEX_NAME: PRIMARY
    62. SEQ_IN_INDEX: 2 -- 索引序号为2
    63. COLUMN_NAME: from_date
    64. COLLATION: A
    65. CARDINALITY: 2760952 -- Cardinality
    66. SUB_PART: NULL
    67. PACKED: NULL
    68. NULLABLE:
    69. INDEX_TYPE: BTREE
    70. COMMENT:
    71. INDEX_COMMENT:
    72. 2 rows in set (0.00 sec)
    73. ---
    74. --- 可以看出,上面两个方法得到的Cardinality的值是相等

    通过 information_schema 数据库可以方便的分析表的元信息。

    检查表的索引创建的情况,判断该索引是否有创建的必要。

    1. --
    2. -- 1. 表的信息如table_schema, table_name, table_rows
    3. -- information_schema.TABLES
    4. --
    5. mysql> show create table TABLES\G
    6. *************************** 1. row ***************************
    7. Table: TABLES
    8. Create Table: CREATE TEMPORARY TABLE `TABLES` (
    9. `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
    10. `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '', -- 表所在的库
    11. `TABLE_NAME` varchar(64) NOT NULL DEFAULT '', -- 表名
    12. `TABLE_TYPE` varchar(64) NOT NULL DEFAULT '',
    13. `ENGINE` varchar(64) DEFAULT NULL,
    14. `VERSION` bigint(21) unsigned DEFAULT NULL,
    15. `ROW_FORMAT` varchar(10) DEFAULT NULL,
    16. `TABLE_ROWS` bigint(21) unsigned DEFAULT NULL, -- 表的记录数
    17. `AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL,
    18. `DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
    19. `MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
    20. `INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
    21. `DATA_FREE` bigint(21) unsigned DEFAULT NULL,
    22. `AUTO_INCREMENT` bigint(21) unsigned DEFAULT NULL,
    23. `CREATE_TIME` datetime DEFAULT NULL,
    24. `UPDATE_TIME` datetime DEFAULT NULL,
    25. `CHECK_TIME` datetime DEFAULT NULL,
    26. `TABLE_COLLATION` varchar(32) DEFAULT NULL,
    27. `CHECKSUM` bigint(21) unsigned DEFAULT NULL,
    28. `CREATE_OPTIONS` varchar(255) DEFAULT NULL,
    29. `TABLE_COMMENT` varchar(2048) NOT NULL DEFAULT ''
    30. ) ENGINE=MEMORY DEFAULT CHARSET=utf8
    31. 1 row in set (0.00 sec)
    32. --
    33. -- 2.information.STATISTICS 中存在 table_schema table_name 信息
    34. --
    35. mysql> show create table STATISTICS\G
    36. *************************** 1. row ***************************
    37. Table: STATISTICS
    38. Create Table: CREATE TEMPORARY TABLE `STATISTICS` (
    39. `TABLE_CATALOG` varchar(512) NOT NULL DEFAULT '',
    40. `TABLE_SCHEMA` varchar(64) NOT NULL DEFAULT '', -- 表所在的库
    41. `TABLE_NAME` varchar(64) NOT NULL DEFAULT '', -- 表名
    42. `NON_UNIQUE` bigint(1) NOT NULL DEFAULT '0',
    43. `INDEX_SCHEMA` varchar(64) NOT NULL DEFAULT '',
    44. `INDEX_NAME` varchar(64) NOT NULL DEFAULT '', -- 索引名
    45. `SEQ_IN_INDEX` bigint(2) NOT NULL DEFAULT '0',
    46. `COLUMN_NAME` varchar(64) NOT NULL DEFAULT '',
    47. `COLLATION` varchar(1) DEFAULT NULL,
    48. `CARDINALITY` bigint(21) DEFAULT NULL,
    49. `SUB_PART` bigint(3) DEFAULT NULL,
    50. `PACKED` varchar(10) DEFAULT NULL,
    51. `NULLABLE` varchar(3) NOT NULL DEFAULT '',
    52. `INDEX_TYPE` varchar(16) NOT NULL DEFAULT '',
    53. `COMMENT` varchar(16) DEFAULT NULL,
    54. `INDEX_COMMENT` varchar(1024) NOT NULL DEFAULT ''
    55. ) ENGINE=MEMORY DEFAULT CHARSET=utf8
    56. 1 row in set (0.00 sec)
    57. --
    58. -- 3. TABLES STATISTICS 表中的table_schematable_name相关联
    59. -- 通过Cardinalitytable_rows 计算,即可得到对应索引名的选择性
    60. --
    61. --
    62. -- 3.1 因为存在复合索引,所以我们要取出复合索引中seq最大的哪个值
    63. -- 这样取出的cardinality值才是最大的
    64. --
    65. mysql> select
    66. -> table_schema, table_name, index_name,
    67. -> max(seq_in_index) -- 取出最大的seq号后,选出index_name等信息
    68. -> from
    69. -> STATISTICS
    70. -> group by table_schema , table_name , index_name\G
    71. -- -----------省略其他输出-----------
    72. *************************** 10. row ***************************
    73. table_schema: burn_test
    74. table_name: test_index_2
    75. index_name: idx_mul_ab -- 这个是上次测试复合索引建立的index
    76. max(seq_in_index): 2 -- 取出了最大的seq
    77. -- -----------省略其他输出-----------
    78. --
    79. -- 3.2得到了最大的seq,从而可以取出对应的cardinality
    80. --
    81. mysql> select
    82. -> table_schema, table_name, index_name, cardinality
    83. -> from
    84. -> STATISTICS
    85. -> where
    86. -> (table_schema , table_name, index_name, seq_in_index) in
    87. -> (select
    88. -> table_schema, table_name,
    89. -> index_name, max(seq_in_index)
    90. -> from
    91. -> STATISTICS
    92. -> group by table_schema , table_name , index_name)\G
    93. *************************** 1. row ***************************
    94. table_schema: burn_test
    95. table_name: Orders
    96. index_name: PRIMARY
    97. cardinality: 5
    98. *************************** 2. row ***************************
    99. table_schema: burn_test
    100. table_name: Orders_MV
    101. index_name: product_name
    102. cardinality: 3
    103. *************************** 3. row ***************************
    104. table_schema: burn_test
    105. table_name: child
    106. index_name: par_ind
    107. cardinality: 0
    108. *************************** 4. row ***************************
    109. table_schema: burn_test
    110. table_name: parent
    111. index_name: PRIMARY
    112. cardinality: 1
    113. *************************** 5. row ***************************
    114. table_schema: burn_test
    115. table_name: t4
    116. index_name: PRIMARY
    117. cardinality: 4
    118. -- -----------省略其他输出-----------
    119. --
    120. -- 3.3 最后通过table_schematable_name 让上述的信息和TABLES表进行关联
    121. --
    122. SELECT
    123. t.TABLE_SCHEMA,t.TABLE_NAME,INDEX_NAME, CARDINALITY, TABLE_ROWS,
    124. CARDINALITY/TABLE_ROWS AS SELECTIVITY -- 得到选择性
    125. FROM
    126. TABLES t, -- 查询的表一,TABLES
    127. (
    128. SELECT
    129. table_schema,
    130. table_name,
    131. index_name,
    132. cardinality
    133. FROM STATISTICS
    134. WHERE (table_schema,table_name,index_name,seq_in_index) IN (
    135. SELECT
    136. table_schema,
    137. table_name,
    138. index_name,
    139. MAX(seq_in_index)
    140. FROM
    141. STATISTICS
    142. GROUP BY table_schema , table_name , index_name )
    143. ) s -- 查询的表二,就是上面3.2的查询结果
    144. WHERE
    145. t.table_schema = s.table_schema -- 通过库关联
    146. AND t.table_name = s.table_name -- 再通过表变量
    147. AND t.table_schema = 'employees' -- 指定某一个库名
    148. ORDER BY SELECTIVITY;
    149. +--------------+--------------+------------+-------------+------------+------------+
    150. | TABLE_SCHEMA | TABLE_NAME | index_name | cardinality | TABLE_ROWS | SELECTIVITY |
    151. +--------------+--------------+------------+-------------+------------+------------+
    152. | employees | dept_emp | dept_no | 8 | 330400 | 0.0000 |
    153. | employees | salaries | PRIMARY | 286271 | 2760952 | 0.1037 |
    154. | employees | dept_manager | dept_no | 9 | 24 | 0.3750 |
    155. | employees | titles | PRIMARY | 296887 | 440887 | 0.6734 |
    156. | employees | dept_emp | PRIMARY | 298761 | 330400 | 0.9042 |
    157. | employees | titles | PRIMARY | 440166 | 440887 | 0.9984 |
    158. | employees | salaries | PRIMARY | 2760952 | 2760952 | 1.0000 |
    159. | employees | dept_manager | PRIMARY | 24 | 24 | 1.0000 |
    160. | employees | titles | PRIMARY | 440887 | 440887 | 1.0000 |
    161. | employees | departments | PRIMARY | 9 | 9 | 1.0000 |
    162. | employees | employees | PRIMARY | 298124 | 298124 | 1.0000 |
    163. | employees | dept_emp | PRIMARY | 330400 | 330400 | 1.0000 |
    164. | employees | dept_manager | PRIMARY | 24 | 24 | 1.0000 |
    165. | employees | departments | dept_name | 9 | 9 | 1.0000 |
    166. +--------------+--------------+------------+-------------+------------+------------+
    167. --
    168. -- 通过最后一列的SELECTIVITY是否接近1,判断该索引创建是否合理
    169. -- 注意:
    170. -- Cardinalitytable_rows的值,都是通过随机采样,预估得到的
    171. -- analyze前后,Cardinality值相差较多,说明该索引是不应该被创建的(页上的记录数值分布不平均)
    172. --
    173. -- 推荐 SELECTIVITY 15% 以上是适合的
    174. --
    175. -- 索引使用情况
    176. --
    177. mysql> select * from x$schema_index_statistics limit 1\G
    178. *************************** 1. row ***************************
    179. table_schema: employees
    180. table_name: employees
    181. index_name: PRIMARY -- 索引名字
    182. rows_selected: 300024 -- 读取的记录数
    183. select_latency: 370177723990 -- 使用该索引读取时总的延迟时间370毫秒(单位是皮秒)
    184. rows_inserted: 0 -- 插入的行数
    185. insert_latency: 0
    186. rows_updated: 0 -- 更新的行数
    187. update_latency: 0
    188. rows_deleted: 0
    189. delete_latency: 0
    190. 1 row in set (0.00 sec)
    191. -- 结合之前的SELECTIVITY和这里的数值,可以更好的判断索引是否合理
    192. -- 重启后数据归0

    索引是要排序的,建立索引越多,排序以及维护成本会很大,插入数据的速度会变慢,所以索引建立的多,不是仅仅是浪费空间,还会降低性能,增加磁盘 IO。

    注意:MySQL 5.6 的版本 STATISTICS 数据存在问题,截止 5.6.28 仍然存在,官方定性为 Bug。在 MySQL 5.6 中使用 mysql.innodb_index_stats 得到索引的选择性(SELECTIVITY)。

    通过 information_schema 数据库,找出用户的表中没有创建主键的表。

    1. mysql> desc information_schema.TABLES; -- 表的元信息
    2. +-----------------+---------------------+------+-----+---------+-------+
    3. | Field | Type | Null | Key | Default | Extra |
    4. +-----------------+---------------------+------+-----+---------+-------+
    5. | TABLE_CATALOG | varchar(512) | NO | | | |
    6. | TABLE_SCHEMA | varchar(64) | NO | | | | -- DB 的名字
    7. | TABLE_NAME | varchar(64) | NO | | | | -- TABLE的名字
    8. | TABLE_TYPE | varchar(64) | NO | | | |
    9. | ENGINE | varchar(64) | YES | | NULL | |
    10. | VERSION | bigint(21) unsigned | YES | | NULL | |
    11. | ROW_FORMAT | varchar(10) | YES | | NULL | |
    12. | TABLE_ROWS | bigint(21) unsigned | YES | | NULL | |
    13. | AVG_ROW_LENGTH | bigint(21) unsigned | YES | | NULL | |
    14. | DATA_LENGTH | bigint(21) unsigned | YES | | NULL | |
    15. | MAX_DATA_LENGTH | bigint(21) unsigned | YES | | NULL | |
    16. | INDEX_LENGTH | bigint(21) unsigned | YES | | NULL | |
    17. | DATA_FREE | bigint(21) unsigned | YES | | NULL | |
    18. | AUTO_INCREMENT | bigint(21) unsigned | YES | | NULL | |
    19. | CREATE_TIME | datetime | YES | | NULL | |
    20. | UPDATE_TIME | datetime | YES | | NULL | |
    21. | CHECK_TIME | datetime | YES | | NULL | |
    22. | TABLE_COLLATION | varchar(32) | YES | | NULL | |
    23. | CHECKSUM | bigint(21) unsigned | YES | | NULL | |
    24. | CREATE_OPTIONS | varchar(255) | YES | | NULL | |
    25. | TABLE_COMMENT | varchar(2048) | NO | | | |
    26. +-----------------+---------------------+------+-----+---------+-------+
    27. 21 rows in set (0.00 sec)
    28. mysql> desc information_schema.COLUMNS; -- 每个列的元信息
    29. +--------------------------+---------------------+------+-----+---------+-------+
    30. | Field | Type | Null | Key | Default | Extra |
    31. +--------------------------+---------------------+------+-----+---------+-------+
    32. | TABLE_CATALOG | varchar(512) | NO | | | |
    33. | TABLE_SCHEMA | varchar(64) | NO | | | | -- DB的名字
    34. | TABLE_NAME | varchar(64) | NO | | | | -- TABLE的名字
    35. | COLUMN_NAME | varchar(64) | NO | | | |
    36. | ORDINAL_POSITION | bigint(21) unsigned | NO | | 0 | |
    37. | COLUMN_DEFAULT | longtext | YES | | NULL | |
    38. | IS_NULLABLE | varchar(3) | NO | | | |
    39. | DATA_TYPE | varchar(64) | NO | | | |
    40. | CHARACTER_MAXIMUM_LENGTH | bigint(21) unsigned | YES | | NULL | |
    41. | CHARACTER_OCTET_LENGTH | bigint(21) unsigned | YES | | NULL | |
    42. | NUMERIC_PRECISION | bigint(21) unsigned | YES | | NULL | |
    43. | NUMERIC_SCALE | bigint(21) unsigned | YES | | NULL | |
    44. | DATETIME_PRECISION | bigint(21) unsigned | YES | | NULL | |
    45. | CHARACTER_SET_NAME | varchar(32) | YES | | NULL | |
    46. | COLLATION_NAME | varchar(32) | YES | | NULL | |
    47. | COLUMN_TYPE | longtext | NO | | NULL | |
    48. | COLUMN_KEY | varchar(3) | NO | | | | -- 列的索引
    49. | EXTRA | varchar(30) | NO | | | |
    50. | PRIVILEGES | varchar(80) | NO | | | |
    51. | COLUMN_COMMENT | varchar(1024) | NO | | | |
    52. | GENERATION_EXPRESSION | longtext | NO | | NULL | |
    53. +--------------------------+---------------------+------+-----+---------+-------+
    54. 21 rows in set (0.01 sec)
    55. -- 这里使用TABLES中的table_schematable_name COLUMNS 中的table_schematable_name做一次关联子查询
    56. -- 不直接用COLUMNS中的table_schematable_name是因为表中会含有多个列,
    57. -- 这样COLUMNS表中的记录(Row)的table_schematable_name会存在重复值,需要再次使用DISTINCT
    58. -- MySQL中执行该语句
    59. SELECT
    60. table_schema, table_name
    61. FROM
    62. information_schema.TABLES --
    63. WHERE
    64. table_name NOT IN (
    65. SELECT DISTINCT
    66. TABLE_NAME
    67. FROM
    68. information_schema.COLUMNS
    69. WHERE
    70. COLUMN_KEY = 'PRI')
    71. AND table_schema NOT IN ('mysql' , 'information_schema',
    72. 'sys', 'performance_schema');
    73. +--------------+----------------------+
    74. | table_schema | table_name |
    75. +--------------+----------------------+
    76. | burn_test | child |
    77. | burn_test | comps_test1 |
    78. | burn_test | comps_test2 |
    79. | burn_test | t1 |
    80. | burn_test | t2 |
    81. | burn_test | t3 |
    82. | burn_test | t5 |
    83. | burn_test | test_1 |
    84. | burn_test | test_222 |
    85. | burn_test | test_ger1 |
    86. | burn_test | test_ger2 |
    87. | burn_test | test_ger3 |
    88. | burn_test | test_index_1 |
    89. | burn_test | test_index_2 |
    90. | burn_test | test_left_join_1 |
    91. | burn_test | test_left_join_2 |
    92. | burn_test | test_proc_1 |
    93. | burn_test | test_rank |
    94. | burn_test | test_rank_2 |
    95. | burn_test | test_union_1 |
    96. | burn_test | test_union_2 |
    97. | burn_test | view_rank |
    98. | burn_test | view_rank_1 |
    99. | dbt3 | time_statistics |
    100. | employees | current_dept_emp |
    101. | employees | dept_emp_latest_date |
    102. +--------------+----------------------+
    103. 26 rows in set (0.06 sec)
    104. -- 上述查询的结果就是数据库中没有主键的表

    作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/ldtgin 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。