sql - 糟糕的 MySQL 连接性能

标签 sql mysql database join query-optimization

我一直在尝试对 MySQL 中的两个表执行连接,查询将运行一两分钟,然后我用完内存而没有得到结果。我远不是数据库专家,所以我不确定我的查询是否写得不好,是否我的一些 MySQL 设置配置不当,或者我是否真的应该完全用我的查询做其他事情。仅供引用,数据库位于我本地的机器上。

我有一个大表(约 200 万条记录),其中一列是小表(约 3000 条记录)的 ID。如果这很重要,则 ID 在大表中不是唯一的,但在小表中是唯一的。我尝试了以下查询的各种形式,但似乎没有任何效果:

SELECT big_table.*, 
       small_table.col 
  FROM big_table 
left outer join small_table on (big_table.small_id = small_table.id)

我正在对确实需要全部 200 万行的数据进行大量分析,但不一定在单个查询中进行。以下是我的“显示创建表”的结果:

'big_table', 'CREATE TABLE 'big_table' (
  'BIG_ID_1', varchar(12) NOT NULL,
  'BIG_ID_2', int(100) NOT NULL,
  'SMALL_ID' varchar(8) DEFAULT NULL,
  'TYPICAL_OTHER_COLUMN' varchar(3) DEFAULT NULL,
  ...
  PRIMARY KEY ('BIG_ID_1', 'BIG_ID_2')
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1'

'small_table', 'CREATE TABLE `small_table` (
  `id`, varchar(8) NOT NULL DEFAULT '''',
  `col`, varchar(1) DEFAULT NULL,
  ...
  PRIMARY KEY (`id`),
  KEY `inx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1'

这是我的一个候选查询的“解释”结果:

id  select_type  table        type    possible_keys   key      key_len  ref                         rows     extra
1   SIMPLE       big_table    ALL     NULL            NULL     NULL     NULL                        1962193       
1   SIMPLE       small_table  eq_ref  PRIMARY,inx_id  PRIMARY  10       db_name.big_table.SMALL_ID  1             

最佳答案

您在单个查询中选择了大约 200 万条记录。根据每行中的数据量,您请求的可能是数百兆字节的数据。

你可能想尝试的事情:

  • 如果您不需要所有列,则查询您需要的列,而不是使用 SELECT table.*
  • 看看您是否可以将部分(或全部)处理移动到数据库,而不是获取数据并在客户端进行处理。
  • 避免一次性将整个结果集读入内存。
  • 一次处理几千行,而不是一次获取所有行。

关于sql - 糟糕的 MySQL 连接性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3742730/

相关文章:

php - 通过php在mysql中用空值更新日期时间

php - MySQL 打印同一条记录两次

php - 在 MySQL 查询中插入 "&"或 "%"等字符

mysql - 隐藏 MySQL 计数列

java - 在java中传递多个值来动态查询

sql - 序列 ALTER RESTART 不会影响序列的当前值

MySQL 创建接受以下开头的检查值的表

node.js - 使用 Express 和 MongoDB 从多个单独的集合中获取数据

sql - 尝试将数据从 Impala Parquet 表复制到非 Parquet 表

SQL,从选择查询中打印一列