我可以使用以下内容选择具有一个条件的多行:
SELECT `Col`, `Col2` FROM `Table` WHERE `Col3` IN (?, ?, ?, ?, ?);
# This selects 5 rows
Run Code Online (Sandbox Code Playgroud)
如果有多个条件(所有整数等于运算),如何做到这一点?
查询需要检查三个条件,所有这三个条件构成了复合主键。
单个查询将选择 10 到 100 行(尽管大多数情况下只有 10 行)——它在性能方面必须很快。这就是为什么使用多个查询不是一个好主意。
该CREATE TABLE
声明是:
CREATE TABLE `Table Name` (
`X` smallint(6) unsigned NOT NULL,
`Y` smallint(6) unsigned NOT NULL,
`Z` smallint(6) unsigned NOT NULL,
`Data` varchar(2048) NOT NULL DEFAULT '',
PRIMARY KEY (`X`,`Y`,`Z`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Run Code Online (Sandbox Code Playgroud)
对于多个查询,可以这样做:
SELECT `One`, `Two` FROM `Table` WHERE `X` = ? AND `Y` = ? AND `Z` = ?;
SELECT `One`, `Two` FROM `Table` WHERE `X` = ? AND `Y` = ? AND `Z` = ?;
SELECT `One`, `Two` FROM `Table` WHERE `X` = ? AND `Y` = ? AND `Z` = ?;
# This selects 3 rows but I don't want to make 3 calls to the database server for that
Run Code Online (Sandbox Code Playgroud)
ype*_*eᵀᴹ 11
您有 2 个基本的语法选项可以在一个查询中执行此操作,还有 2 个选项用于确定是发送查询中的值还是首先将它们加载到表中:
正常的AND
/ OR
(这里的括号是多余的,但最好将它们与 一起使用OR
,以防万一WHERE
变得更复杂):
WHERE ( ( x = ? AND y = ? AND z = ? )
OR ( x = ? AND y = ? AND z = ? )
...
OR ( x = ? AND y = ? AND z = ? )
)
Run Code Online (Sandbox Code Playgroud)IN
与“行构造函数”紧凑:
WHERE (x,y,z) IN ((?,?,?), (?,?,?), ...)
Run Code Online (Sandbox Code Playgroud)在(临时)表中加载三元组,并且JOIN
:
CREATE (TEMPORARY) TABLE tmp_table
--- ;
INSERT INTO tmp_table (x,y,z)
VALUES (?,?,?), (?,?,?), ... ;
SELECT t.*
FROM my_table AS t
JOIN tmp_table AS tmp
ON ( t.x = tmp.x AND t.y = tmp.y AND t.z = tmp.z )
;
Run Code Online (Sandbox Code Playgroud)或者:
ON (t.x, t.y, t.z) = (tmp.x, tmp.y, tmp.z)
Run Code Online (Sandbox Code Playgroud)前 2 个选项是等效的,但它们的效率可能会有所不同,具体取决于版本。这种IN
与元组(行构造函数)的语法在旧版本中不能最有效地使用索引。在 5.7 中,优化器将两种语法标识为等效(请参阅MySQL 文档:行构造函数表达式优化)。测试!
当您想查询多个参数/三元组时,使用表的另一种选择可能会更好。您还可以索引(临时)表。测试!
因此,基本建议是在您的版本/配置/设置中进行测试,表格的大小与其预测的大小相似,并且具有不同数量的参数。
还有两种可能值得测试的方法:
简单的UNION ALL
. 因为我们只想运行多个相同的查询,其中只有参数不同。一个缺点是,如果基本查询很复杂并且您有许多三元组要检查,则查询会变得非常长且看起来很笨拙:
SELECT t.* FROM my_table AS t
WHERE ( x = ? AND y = ? AND z = ? ) UNION ALL
SELECT t.* FROM my_table AS t
WHERE ( x = ? AND y = ? AND z = ? ) UNION ALL
---
SELECT t.* FROM my_table AS t
WHERE ( x = ? AND y = ? AND z = ? ) ;
Run Code Online (Sandbox Code Playgroud)UNION ALL
在JOIN
变体中使用派生表(带有)。这可能会使用优化(在 5.5 或 5.6 中添加),可以实现和索引派生表:
SELECT t.*
FROM my_table AS t
JOIN
( SELECT ? AS x, ? AS y, ? AS z UNION ALL
SELECT ?, ?, ? UNION ALL
---
SELECT ?, ?, ?
)
AS tmp
ON ( t.x = tmp.x AND t.y = tmp.y AND t.z = tmp.z )
;
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
48565 次 |
最近记录: |