最优化比较两个MySQL大表中的数据

问题描述 投票:0回答:1

我如何优化查询,这将找到所有记录,其中:

  • 具有activation_request.date_confirmed不为null

  • 在另一个表中没有相关的字符串值:activation_request.email =user.username不应返回任何记录

我尝试过:

SELECT  email 
FROM activation_request l 
    LEFT JOIN user r ON r.username = l.email 
WHERE l.date_confirmed is not null 
AND r.username IS NULL

SELECT email 
FROM  activation_request 
WHERE  date_confirmed is not null 
AND NOT EXISTS (SELECT 1 
                FROM user  
                WHERE  user.username = activation_request.email
                )

但是两个表都有xxx.xxx.xxx记录,因此,整夜都在运行那些查询后,不幸的是我没有任何结果。

创建语句:

CREATE TABLE `activation_request` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `date_confirmed` datetime DEFAULT NULL,
  `email` varchar(255) NOT NULL,
  (...)
  PRIMARY KEY (`id`),
  KEY `emailIdx` (`email`),
  KEY `reminderSentIdx` (`date_reminder_sent`),
  KEY `idx_resent_needed` (`date_reminder_sent`,`date_confirmed`),
) ENGINE=InnoDB AUTO_INCREMENT=103011867 DEFAULT CHARSET=utf8;




CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `version` bigint(20) NOT NULL,
  `username` varchar(255) NOT NULL,
  (...)
  PRIMARY KEY (`id`),
  UNIQUE KEY `Q52plW9W7TJWZcLj00K3FmuhwMSw4F7vmxJGyjxz5iiINVR9fXyacEoq4rHppb` (`username`),
) ENGINE=InnoDB AUTO_INCREMENT=431400048 DEFAULT CHARSET=latin1;

向左加入的解释:

[[id:1,select_type:SIMPLE,表:l,类型:ALL,可能的键:空,key:null,key_len:null,ref:null,rows:49148965,Extra:Using where],[id:1,select_type:SIMPLE,table:r,type:index,可能的keys:null,密钥:Q52plW9W7TJWZcLj00K3FmuhwMSw4F7vmxJGyjxz5iiINVR9fXyacEoq4rHppb,key_len:257,ref:null,行数:266045508,Extra:在哪里使用;不存在;使用索引;使用连接缓冲区(块嵌套循环)]] [[id:1,select_type:SIMPLE,表:l,类型:ALL,可能的键:空,键:空,key_len:null,ref:null,行:49148965,Extra:在哪里使用,[id:1,select_type:SIMPLE,table:r,type:index,可能的keys:null,密钥:Q52plW9W7TJWZcLj00K3FmuhwMSw4F7vmxJGyjxz5iiINVR9fXyacEoq4rHppb,key_len:257,ref:null,行数:266045508,Extra:在哪里使用;不存在;使用索引;使用连接缓冲区(块嵌套循环)]]

在临时数据库上添加索引后(数据略少,但结构相同)现在正在运行〜24h,但仍然没有结果:

$ show processlist;

| Id | User    | Host                                            | db       | Command | Time   | State        | Info 
| 64 | root    | localhost                                       | staging_db   | Query   | 110072 | Sending data | SELECT ar.email FROM  activation_request ar WHERE ar.date_confirmed is not null AND NOT EXISTS (SELE |

Mysql版本:

$ select version();
5.6.16-1~exp1

列表上的所有其他命令均为Sleep,因此没有其他查询在运行,并且可能会干扰/锁定行。

mysql sql performance query-performance
1个回答
0
投票

对于此查询:

SELECT ar.email 
FROM  activation_request ar
WHERE ar.date_confirmed is not null AND
      NOT EXISTS (SELECT 1 
                  FROM user u
                  WHERE u.username = ar.email
                 )

我建议在activation_request(date_confirmed, email)user(username)上使用索引。

不过,除非您有大量的数据,否则您的问题可能是表已锁定。

© www.soinside.com 2019 - 2024. All rights reserved.