mysql - 使用子查询在 mysql 基础上删除非常慢

标签 mysql subquery config sql-delete

这个 mysql 查询运行了大约 10 个小时,还没有完成。出了点大问题。

这里有两个表(文本和垃圾邮件)。垃圾邮件将垃圾邮件条目的 ID 存储在我要删除的文本中。

DELETE FROM tname.text WHERE old_id IN (SELECT textid FROM spam);

垃圾邮件只有 2 列,都是整数。 800K 条目的文件大小为数 Mb。两个整数都是主键。

文本有 3 列。 id(主键)、文本、标志。大约 1200K 个条目,大约 2.1 GB 大小(大多数垃圾邮件)。

服务器是 xeon quad,2 GB 内存(不要问我为什么)。只有 apache(为什么?)和 mysqld 正在运行。它是一个旧的免费 bsd 和 mysql 4.1.2(不要问我为什么)

线程:6 个问题:188805 慢速查询:318 打开:810 刷新表:1 打开表:每秒 157 次查询平均:7.532

Mysql my.cnf:

[mysqld]
datadir=/usr/local/mysql
log-error=/usr/local/mysql/mysqld.err
pid-file=/usr/local/mysql/mysqld.pid
tmpdir=/var/tmp
innodb_data_home_dir =
innodb_log_files_in_group = 2
join_buffer_size=2M
key_buffer_size=32M
max_allowed_packet=1M
max_connections=800
myisam_sort_buffer_size=32M
query_cache_size=8M
read_buffer_size=2M
sort_buffer_size=2M
table_cache=256
skip-bdb
log-slow-queries = slow.log
long_query_time = 1

#skip-innodb
#default-table-type=innodb
innodb_data_file_path = /usr/local/mysql/ibdata1:10M:autoextend
innodb_log_group_home_dir = /usr/local/mysql/
innodb_buffer_pool_size = 128M
innodb_log_file_size = 16M
innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit=1
#innodb_additional_mem_pool_size=1M
#innodb_lock_wait_timeout=50

log-bin
server-id=201

[isamchk]
key_buffer_size=128M
read_buffer_size=128M
write_buffer_size=128M
sort_buffer_size=128M

[myisamchk]
key_buffer_size=128M[server:~] dmesg | grep memory
real memory  = 2146828288 (2047 MB)
avail memory = 2095534080 (1998 MB)

read_buffer_size=128M
write_buffer_size=128M
sort_buffer_size=128M
tmpdir=/var/tmp

查询仅使用一个 cpu,top 表示 25% cpu 时间(因此 4 个中的 1 个)。

real memory  = 2146828288 (2047 MB)
avail memory = 2095534080 (1998 MB)

62 processes:  2 running, 60 sleeping
CPU states: 25.2% user,  0.0% nice,  1.6% system,  0.0% interrupt, 73.2% idle
Mem: 244M Active, 1430M Inact, 221M Wired, 75M Cache, 112M Buf, 31M Free
Swap: 4096M Total, 1996K Used, 4094M Free

  PID USERNAME     THR PRI NICE   SIZE    RES STATE  C   TIME   WCPU COMMAND
11536 mysql         27  20    0   239M   224M kserel 3 441:16 94.29% mysqld

知道如何解决吗?

最佳答案

根据我的经验,子查询通常是导致 SQL 语句执行时间变慢的原因,因此我尽量避免它们。试试这个:

DELETE tname FROM tname INNER JOIN spam ON (tname.old_id = spam.textid);

免责声明:此查询未经测试,请先备份! :-)

关于mysql - 使用子查询在 mysql 基础上删除非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7361174/

相关文章:

Mysql 查询列出从一个表到另一个表的字段值

MySQL 按类型分组,然后按列中的日期范围进行切片

c# - .Net Core 3.0 可执行文件不读取 appsettings.json

F# NLog 配置文件

mysql - 从子查询中选择列

c# - 未创建控制台应用程序的设置文件

java - HQL 等价于 hibernate 中标准查询的多对多关系查询?

php - 如何将动态添加的文本框(JavaScript)中的多个数据保存到MySQL数据库中?

php - 在 MVC 环境中使用 ORM 有充分的理由吗?

mysql - 如何在单行中获取最小值和最大值以及相应的 id