2014-02-26 133 views
1

这里的基本查询:唯一的记录没有加入DISTINCT或GROUP BY

SELECT 
    some_columns 
FROM 
    d 
JOIN 
    m ON d.id = m.d_id 
JOIN 
    s ON s.id = m.s_id 
JOIN 
    p ON p.id = s.p_id 
WHERE 
    some_criteria 
ORDER BY 
    d.date DESC 
LIMIT 25 

m可以按每个d_id包含多个s_id秒。这里有一个非常简单的例子:

+--------+--------+------+ 
| id  | d_id | s_id | 
+--------+--------+------+ 
| 317354 | 291220 | 642 | 
| 317355 | 291220 | 32 | 
+--------+--------+------+ 
2 rows in set (0.00 sec) 

我们想要的。但是,很明显,它在这个特定的查询中生成重复的d记录。

这些表有很多列,我需要编辑这些下由于数据的敏感性质,但这里的基本结构,因为它涉及到这个查询:

| d | CREATE TABLE `d` (
    `id` bigint(22) unsigned NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`), 
    KEY `date` (`date`) 
) ENGINE=InnoDB | 

| m | CREATE TABLE `m` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT, 
    `d_id` bigint(20) NOT NULL, 
    `s_id` bigint(20) NOT NULL, 
    `is_king` binary(1) DEFAULT '0', 
    PRIMARY KEY (`id`), 
    KEY `d_id` (`d_id`), 
    KEY `is_king` (`is_king`), 
    KEY `s_id` (`s_id`) 
) ENGINE=InnoDB | 

| s | CREATE TABLE `s` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    `p_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `p_id` (`p_id`) 
) ENGINE=InnoDB | 

| p | CREATE TABLE `p` (
    `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB | 

现在,此前,我们有一个GROUP BY d.id来抓独特。这里的数据现在很庞大,所以我们不能再现实地做到这一点。 SELECT DISTINCT d.id更慢。

任何想法?我想出的一切都会在别处产生问题。

+0

子查询而不是联接? – Hackerman

+0

请为每个人发布'SHOW CREATE TABLE'。他们是否有索引定义?他们是否在加入的列上定义了“FOREIGN KEY”关系(这会强制执行适当的索引)?只有这一点可能会使性能得到巨大的改善。 –

+0

如果你可以保证所有的连接都会得到匹配,你可以做选择限制,并在连接之后进行。如果你不能以少于25行的方式结束 – jean

回答

0

将“JOIN m ON d.id = m.d_id”更改为“LEFT JOIN m ON d.id = m.d_id”是否可以完成您在此寻找的任务?

我不知道我明白你的目标,但“每个d包含许多行”我立即想知道你是否应该使用其他类型的连接来完成你的目标。