这是根据post post params动态生成的大查询的一部分......
有一个表user_params
id | user_id | param_id | param_value
--------------------------------------
1 | 5 | 2 | audi
--------------------------------------
2 | 5 | 3 | a4
--------------------------------------
3 | 5 | 4 | silver
--------------------------------------
4 | 7 | 2 | audi
--------------------------------------
5 | 7 | 3 | q3
--------------------------------------
6 | 8 | 2 | ford
--------------------------------------
7 | 8 | 3 | fiesta
--------------------------------------
我想提取所有' user_id'其中' param_id' = 1,' param_value' =' audi' ,' param_id' = 3,' param_value' =' a4'
因此,在这种情况下,我的结果应包含id
行1,2,4,5,7。
考虑到这个表有超过50K的条目,最好的方法是什么?
它是InnoDB表。
+++现在我看到有一个带有这些表的多选字段的html表单。 "给我所有驾驶奥迪(a4或q3)或VW(帕萨特)的用户(user_id)是银色的#34;。
我正在测试您撰写的解决方案。
答案 0 :(得分:2)
您必须在同一个表上执行多个连接。
一种方法就是这样
SELECT
t1.user_id
FROM
thetable AS t1,
thetable AS t2,
thetable AS t3
WHERE
t1.user_id = t2.user_id AND t2.user_id=t3.user_id AND
t1.param_id = 1 AND t1.param_value = 'audi' AND
t2.param_id = 3 AND t2.param_value = 'a4' AND
t3.param_id = 4 AND t3.param_value = 'silver'
这相当于使用JOIN
语句,但它只是提供了这个想法。
当然,查询必须根据您要检查的参数数量进行扩展或缩小(在示例中为3)。
如果所有字段都被编入索引,则查询应该在50K记录上运行得非常快。
答案 1 :(得分:1)
如果您想加快速度,可以将索引添加到受影响的列。但实际上没有DBM应该有50k数据集的问题。它没那么多。
答案 2 :(得分:1)
好的,我实际上已经开始根据您在此处发布的示例数据创建了一个测试表,这里是创建语句:
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) DEFAULT NULL,
`param_id` int(11) DEFAULT NULL,
`param_value` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
接下来,我在这里用数据
填充它INSERT INTO `test`
(
`user_id`,
`param_id`,
`param_value`
)
VALUES
(5,2, 'audi'),
(5,3, 'a4'),
(5,4, 'silver'),
(7,2, 'audi'),
(7,3, 'q3'),
(8,2, 'ford'),
(8,3, 'fiesta');
然后,以下是我尝试的各种查询:
/** using OR + DISTINCT **/
SELECT DISTINCT user_id
FROM test
WHERE (param_id = 1 AND param_value = 'audi')
OR (param_id = 3 AND param_value = 'a4')
OR (param_id = 4 AND param_value = 'silver')
/** using OR + GROUP BY **/
SELECT user_id
FROM test
WHERE (param_id = 1 AND param_value = 'audi')
OR (param_id = 3 AND param_value = 'a4')
OR (param_id = 4 AND param_value = 'silver')
GROUP BY user_id
/** Using tripple join **/
SELECT
t1.user_id
FROM
test AS t1,
test AS t2,
test AS t3
WHERE
t1.user_id = t2.user_id AND t2.user_id=t3.user_id AND
t1.param_id = 2 AND t1.param_value = 'audi' AND
t2.param_id = 3 AND t2.param_value = 'a4' AND
t3.param_id = 4 AND t3.param_value = 'silver'
/** JOIN with ON clause instead of WHERE **/
SELECT
t1.user_id
FROM
test AS t1
JOIN
test AS t2
ON t1.user_id = t2.user_id
JOIN
test AS t3
ON t3.user_id = t1.user_id
WHERE
t1.param_id = 2 AND t1.param_value = 'audi' AND
t2.param_id = 3 AND t2.param_value = 'a4' AND
t3.param_id = 4 AND t3.param_value = 'silver'
所有这些查询都会产生相同的结果。但是,获得结果的方式确实非常不同,显示在EXPLAIN EXTENDED
输出中,您现在可以通过运行所有这些查询轻松查看,并预先EXPLAIN EXTENDED
,因为我&# 39;我只是懒得在ATM上粘贴所有输出
您应该看到的是JOIN
个查询都显示为连接类型ALL
,这意味着整个表格被扫描(3次),rows
计数反映出,每个JOIN影响所有7行(总共21行)
相比之下,JOIN
- 更少的查询,只需要扫描7行,我认为在这种情况下,加入可能不是答案。
答案 3 :(得分:0)
嗯,术语'param_id' = 1 AND 'param_value' = 'audi' AND 'param_id' = 3 AND 'param_value' = 'a4'
总是错误的,所以我假设你想要使用(param_id = 1 AND param_value = 'audi') OR (param_id = 3 AND 'param_value' = 'a4')
在这种情况下,查询可能类似于:select distinct user_id where (param_id = 1 AND param_value = 'audi') OR (param_id = 3 AND 'param_value' = 'a4')
答案 4 :(得分:0)
如果您每次都使用AND进行尝试,则无法获得任何值。它的作用是尝试获得一个param_id为1的user_id,其值为audi,param_id为3,param_value为a4。你需要尝试使用OR,我不会看到任何param_id为1,所以要确保一个存在。如果我正确理解你的问题,你需要做一些像
这样的事情SELECT user_id FROM tablename WHERE 'param_id' = 1 AND 'param_value' = 'audi' OR 'param_id' = 3 AND 'param_value' = 'a4'
答案 5 :(得分:0)
请在下面查询条件中的条件
where param_id in (1,3) && param_value in ('audi','a4')