我有两个表用于存储产品,其他用于存储订单列表。
CREATE TABLE ProductsList(ProductId INT NOT NULL PRIMARY KEY, ProductName VARCHAR(50)) INSERT INTO ProductsList(ProductId, ProductName) VALUES(1,'Product A'), (2,'Product B'), (3,'Product C'), (4,'Product D'), (5,'Product E'), (6,'Product F'), (7,'Product G'), (8,'Product H'), (9,'Product I'), (10,'Product J'); CREATE TABLE OrderList(OrderId INT NOT NULL PRIMARY KEY AUTO_INCREMENT, EmailId VARCHAR(50), CSVProductIds VARCHAR(50)) INSERT INTO OrderList(EmailId, CSVProductIds) VALUES('PersonA@domain.com', '2,4,1,5,7'), ('PersonB@domain.com', '5,7,4'), ('PersonC@domain.com', '2'), ('PersonD@domain.com', '8,9'), ('PersonE@domain.com', '4,5,9'), ('PersonF@domain.com', '1,2,3'), ('PersonG@domain.com', '9,10'), ('PersonH@domain.com', '1,5');
输出
ItemName NoOfOrders
Product A 3
Product B 3
Product C 1
Product D 3
Product E 4
Product F 0
Product G 2
Product H 1
Product I 3
Product J 1
订单列表将ItemsId存储为每个下订单的客户的逗号分隔值。就像我在我的dB表中有超过40k的记录
现在,我被分配了一个创建报告的任务,在该任务中我应该显示项目和下面显示的人员订购项目
我在PHP中使用了以下查询,将Orders One By One和存储在数组中。
SELECT COUNT(PL.EmailId)
FROM OrderList PL
WHERE CSVProductIds LIKE '2' OR
CSVProductIds LIKE '%,2,%' OR
CSVProductIds LIKE '%,2' OR
CSVProductIds LIKE '2,%';
1.使用单一查询
可以获得相同的输出2.当表中有更多的记录,即40k行
时,在mysql查询中使用like会减慢dB的速度答案 0 :(得分:6)
是的,使用带有前导通配符的LIKE强制它执行表扫描,即读取表中的每一行。桌子越大,它就越慢。例如,它可能要慢几百或几千倍!
这是将逗号分隔列表存储在VARCHAR中并期望访问单个元素的几个原因之一,这对于关系数据库来说是一个糟糕的设计。
另请参阅我对Is storing a comma separated list in a database column really that bad?
的回答您应该做的是定义您的OrderList表以存储一对电子邮件和productid。如果订单包含多个产品,则必须存储多行。但这意味着您可以随时找到您正在寻找的单一产品,计算购买该产品的人数等等,并且您可以通过定义索引来快速查询这些查询。
将列表存储在单个列中的规则称为First Normal Form。
答案 1 :(得分:0)
1.使用正则表达式,但认为它只会更改您的应用程序代码而不是数据库代码 2.它通常会影响shortly mentioned here和here's a solution可能有帮助的效果。
答案 2 :(得分:-1)
你可以在下面找到它
SELECT COUNT(PL.EmailId)
FROM OrderList PL
WHERE FIND_IN_SET(2, CSVProductIds)