具有 JOIN 和 GROUP BY 优化的 MySQL 查询。可能吗?

标签 mysql sql query-optimization

我有两个表:gpnxuser 和 key_value

mysql> describe gpnxuser;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version      | bigint(20)   | NO   |     | NULL    |                |
| email        | varchar(255) | YES  |     | NULL    |                |
| uuid         | varchar(255) | NO   | MUL | NULL    |                |
| partner_id   | bigint(20)   | NO   | MUL | NULL    |                |
| password     | varchar(255) | YES  |     | NULL    |                |
| date_created | datetime     | YES  |     | NULL    |                |
| last_updated | datetime     | YES  |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

mysql> describe key_value;
+----------------+--------------+------+-----+---------+----------------+
| Field          | Type         | Null | Key | Default | Extra          |
+----------------+--------------+------+-----+---------+----------------+
| id             | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| version        | bigint(20)   | NO   |     | NULL    |                |
| date_created   | datetime     | YES  |     | NULL    |                |
| last_updated   | datetime     | YES  |     | NULL    |                |
| upkey          | varchar(255) | NO   | MUL | NULL    |                |
| user_id        | bigint(20)   | YES  | MUL | NULL    |                |
| security_level | int(11)      | NO   |     | NULL    |                |
+----------------+--------------+------+-----+---------+----------------+

key_value.user_id 是引用 gpnxuser.id 的 FK。我在 gpnxuser.partner_id 中也有一个索引,它是一个 FK,它引用了一个名为“partner”的表(我认为这对这个问题来说并不重要)。

对于 partner_id = 64,我在 gpnxuser 中有 500K 行,它们与 key_value 中大约 6M 行有关系。

我想要一个查询,为属于给定合作伙伴的用户返回所有不同的“key_value.upkey”。我做了这样的事情:

select upkey from gpnxuser join key_value on gpnxuser.id=key_value.user_id where partner_id=64 group by upkey;

需要永远运行。查询的解释如下:

mysql> explain select upkey from gpnxuser join key_value on gpnxuser.id=key_value.user_id where partner_id=64 group by upkey;

    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+
    | id | select_type | table     | type | possible_keys              | key                | key_len | ref                         | rows   | Extra                                        |
    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+
    |  1 | SIMPLE      | gpnxuser  | ref  | PRIMARY,FKB2D9FEBE725C505E | FKB2D9FEBE725C505E | 8       | const                       | 259640 | Using index; Using temporary; Using filesort |
    |  1 | SIMPLE      | key_value | ref  | FK9E0C0F912D11F5A9         | FK9E0C0F912D11F5A9 | 9       | gpnx_finance_db.gpnxuser.id |     14 | Using where                                  |
    +----+-------------+-----------+------+----------------------------+--------------------+---------+-----------------------------+--------+----------------------------------------------+

我的问题是:有没有可以快速运行并获得我想要的结果的查询?

最佳答案

您需要做的是利用EXISTS 语句:这只会导致部分表扫描,直到找到匹配项,而不是更多。

select upkey from (select distinct upkey from key_value) upk 
where EXISTS 
    (select 1 from gpnxuser u, key_value kv 
     where u.id=kv.user_id and partner_id=1 and kv.upkey = upk.upkey)

注意。在原始查询中,group by 被滥用:distinct 在那里看起来更好。

select DISTINCT upkey from gpnxuser join key_value on 
gpnxuser.id=key_value.user_id where partner_id=1

关于具有 JOIN 和 GROUP BY 优化的 MySQL 查询。可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16107428/

相关文章:

c# - 用于存储加密字段数据的最佳数据类型

mysql - SQL 按最高金额 "kills divided by deaths"排序

sql - 未使用自己的键连接表时的连接行为

python - Pandas 数据帧 to_sql 数据长度超过 65536 个字符

c# - 我可以访问 Entity Framework 中 IDbCommandInterceptor 中的实体吗

mysql - 在 JOINING 之前选择 SELECT 会更好吗?

sql-server - 组合索引与多个单一索引与全文索引的查询性能

mysql - 将 SQL 查询转换为 MySQL

php - mysql isnumeric sql注入(inject)

mysql - 从 mysql 数据库操作系统大小 700Mb 中快速选择最后 n 条记录