内查询多列一库
Posted
技术标签:
【中文标题】内查询多列一库【英文标题】:Inner Query Multiple Columns One Database 【发布时间】:2018-04-27 11:48:56 【问题描述】:我有 SQL 表。它存储用户正在执行的任务。该表有 1 个主键(自动生成)。它有 4 列,例如:Name、BadgeID、LoginID、Task,用户可以查询这些列Name、BadgeID 或 LoginID 列来获取数据。在所有 3 列上创建索引。但是Column中的数据是相互关联的。
例如,表格:
PrimKey Name BadgeID LoginID Task
1 John Wick 1234 wick Entered Office
2 1234 Printing
3 John Wick 6789 jwic Entered Office
4 Max Payne payn Printing
在进入办公室时,用户必须提供姓名,并且必须提供 BadgeID 或 LoginID 中的至少一个,他也可以同时提供两者。对于打印任务,他必须仅提供 BadgeID 或 LoginID。如果您在办公室外使用打印机,也可以在不进入办公室的情况下执行打印任务。
对于查询数据库,用户可以使用 Name、BadgeID 或 LoginID 中的任何一个查询表。
如果用户使用Name = John Wick
进行查询,那么他应该得到所有 3 个结果。
如果用户使用BadgeID = 1234
查询,那么他应该得到1 和2,如果他使用BadgeID = 6789
查询,那么他应该只得到3。
如果用户使用LoginID = wick
查询,那么他应该得到1 和2,如果他使用LoginID = jwic
查询,那么他应该只得到3。
我写的 SQL 查询是:
以下查询需要 15 秒:
SELECT *
FROM table
WHERE (BadgeID IN (select distinct BadgeID
from table
WHERE $idType = $id)
OR LoginID IN (select distinct LoginID
from table
WHERE $idType = $id))
进一步优化:
SELECT *
FROM table
WHERE BadgeID IN (select distinct BadgeID
from table
WHERE $idType = $id)
UNION
SELECT *
FROM table
WHERE LoginID IN (select distinct LoginID
from table
WHERE $idType = $id);
第二个查询要快一点,但看起来丑陋且不可读。有没有一种方法可以通过只扫描表两次而不是 3 次来实现?
附:我正在使用 mysql-5.6。
【问题讨论】:
修复表格,使所有列都有值。您可能需要为此触发。 @GordonLinoff 但这是在修改实际的产品数据。当代码仅发送 BadgeID 或 LoginID 时,5 年后查看它的用户会混淆打印调用如何具有名称。此外,也不是可扩展的模型,如果任何新 ID 假设将来还会出现 EmployeeID,那么旧条目也需要修改。 我确定您不需要子查询中的 distinct 部分? 【参考方案1】:保持上次查询的相同结构,强烈建议:
如果您能确保不会出现重复,请使用UNION ALL
,这样会更快。
用列名代替*
。
这两个基本技巧将帮助您更快地执行。不要忘记为您的表编制索引。
【讨论】:
【参考方案2】:数据存储是数据的存储库,而不是格式化引擎。
“如果用户使用 LoginID = wick 进行查询,那么他应该得到 1 和 2”——这就是应该存储在表中的内容!
在输出中删除wick
是格式问题,由应用程序执行!
也许您需要一个包含BadgeID
和LoginID
的单独表,以便wick
始终与1234
关联?这意味着架构的重组。
【讨论】:
以上是关于内查询多列一库的主要内容,如果未能解决你的问题,请参考以下文章