1

製品を保存するためのテーブルと注文リストを保存するためのテーブルの 2 つがあります。

CREATE TABLE ProductsList(ProductId INT NOT NULL PRIMARY KEY,
                          商品名 VARCHAR(50))


INSERT INTO ProductsList(ProductId, ProductName)
                  VALUES(1,'商品A'),
                        (2,'商品B'),
                        (3,'商品C'),
                        (4、「製品 D」)、
                        (5、「製品 E」)、
                        (6,'商品F'),
                        (7,'商品G'),
                        (8,'製品H'),
                        (9,'製品 I'),
                        (10,'製品 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テーブルに40,000を超えるレコードがあります

ここで、以下に示すように、アイテムと注文したアイテムの人数を表示するレポートを作成するタスクが割り当てられています

PHPで次のようにクエリを使用して、注文を1つずつ取得し、配列に保存しました。

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.mysqlクエリでlikeを使用すると、テーブルのレコード数が40k行を超えるとdBが遅くなります

4

3 に答える 3

6

はい、先頭にワイルドカードを付けて LIKE を使用すると、強制的にテーブル スキャンが実行されます。つまり、テーブル内のすべての行が読み取られます。テーブルが大きいほど遅くなります。たとえば、数百倍または数千倍遅くなる可能性があります。

これは、カンマ区切りのリストを VARCHAR に格納し、個々の要素にアクセスすることを期待することが、リレーショナル データベースの設計として不適切である理由の 1 つです。

への私の回答も参照してくださいデータベースの列にカンマ区切りのリストを保存しているのは本当に悪いですか?

代わりに、OrderList テーブルを定義して、email と productid のペアを1 つ格納する必要があります。注文が複数の製品で構成されている場合は、複数の行を保存する必要があります。ただし、探している単一の製品をいつでも見つけたり、その製品を購入した人数を数えたりすることができ、インデックスを定義することでこれらのクエリを高速に実行できることを意味します。

リストを 1 つの列に格納しない規則は、第 1 正規形と呼ばれます。

于 2012-12-17T05:00:42.197 に答える
0

1.正規表現を使用しますが、db コードではなくアプリケーション コードのみを変更することを考慮してください。
2.はい、通常はパフォーマンスに影響しますが、これについてはここで簡単に説明します。ここに役立つ解決策があります。

于 2012-12-17T05:02:54.430 に答える
-1

あなたはそれを以下のようなシングルで見つけることができます

SELECT COUNT(PL.EmailId)
  FROM OrderList PL 
 WHERE FIND_IN_SET(2, CSVProductIds) 
于 2012-12-28T07:20:30.483 に答える