我在sql表上有一个。它存储用户正在执行的任务。该表有1个主键(自动生成)。它有4列,例如:name、badgeid、loginid、task,用户可以在上面查询name、badgeid或loginid列来获取数据。在所有3列上创建索引。但列中的数据是相互关联的。
例如,表:
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});
第二个查询稍微快一点,但是看起来很难看,不可读。有没有办法只扫描两次表,而不是扫描三次?
p、 我使用的是mysql-5.6。
2条答案
按热度按时间nhjlsmyf1#
数据存储是数据存储库,而不是格式化引擎。
“如果用户使用loginid=wick进行查询,那么他应该得到1和2”--这就是应该存储在表中的内容!
消隐
wick
在输出中是一个格式化问题,由应用程序执行!也许你需要一张单独的table
BadgeID
以及LoginID
以便wick
总是与1234
? 这意味着架构的重组。ao218c7q2#
保持上次查询的结构不变,强烈建议您:
使用
UNION ALL
如果你能保证不会有复制品,那就快多了。而不是
*
列的名称。这两个基本技巧将帮助你更快地完成任务。别忘了给你的表编索引。