3

データベースに次のテーブルがあり、変更または修正できません。LogテーブルはシンプルにしましたLogDetailが、データベースと同じです。

ログテーブル

 Id  User Department Service     Method

 21  John Sales      UserService GetUser

LogDetail テーブル

Id LogRef ParamName  ParamValue

30 21     FirstName  Adam
31 21     LastName   Smith     
32 21     Age        35
33 21     Gender     M

今、私は次のクエリを使用して、誰が検索したかを取得しています(Adam、Smith、35、M)

SELECT 
L.*, D1.ParamName, D2.ParamName, D3.ParamName, D4.ParamName
FROM Log as L
INNER JOIN LogDetail as D1 on L.Id = D1.LogRef
INNER JOIN LogDetail as D2 on L.Id = D2.LogRef
INNER JOIN LogDetail as D3 on L.Id = D3.LogRef
INNER JOIN LogDetail as D4 on L.Id = D4.LogRef
WHERE
D1.ParamName='FirstName' and D1.ParamValue='Adam' and
D2.ParamName='LastName' and D2.ParamValue='Smith' and
D3.ParamName='Age' and D3.ParamValue=35 and
D4.ParamName='Gender' and D4.ParamValue='M'

これを行うより良い方法はありますか?

4

3 に答える 3

6

これは、 EAVスキーマ (基本的にはキーと値のペア)を使用するとどうなるかです。

(ParamName, ParamValue)にインデックスを追加する以外にできることはあまりありませんLogDetail。これは、クラスター化インデックスがそのまま維持されることを前提としています。LogRef

于 2012-05-31T09:41:14.193 に答える
1

キーと値のペアをより使いやすいものに集約するビューを作成することにより、クエリを単純化する1つの方法:

CREATE VIEW ViewLogUsers
AS
SELECT UFN.LogRef, UFN.ParamName AS FirstName, ULN.ParamName AS LastName, UAG.ParamName AS Age, UGE.ParamName AS Gender
FROM LogDetail AS UFN
INNER JOIN LogDetail AS ULN ON UFN.LogRef = ULN.LogRef
INNER JOIN LogDetail AS UAG ON UFN.LogRef = UAG.LogRef
INNER JOIN LogDetail AS UGE ON UFN.LogRef = UGE.LogRef
WHERE UFN.ParamName = 'Firstname' AND ULN.ParamName = 'LastName' AND UAG.ParamName = 'Age' AND UGE.ParamName = 'Gender'
GO

次に、元のクエリは次のようになります。

SELECT 
L.*, D1.FirstName, D1.LastName, D1.Age, D1.Gender
FROM Log as L
INNER JOIN ViewLogUsers as D1 on L.Id = D1.LogRef
WHERE D1.FirstName = 'Adam' AND D1.LastName = 'Smith' AND D1.Age = '35' AND D1.Gender = 'M'

ビューと同じ構造でテーブルを作成した場合よりもパフォーマンスは大幅に低下しますが(ただし、インデックス付きビューを使用できる場合は役立ちます)、少なくとも使用する方がはるかに簡単です。 。

于 2012-05-31T10:07:06.550 に答える
1

Index結合句で使用されるフィールドで使用できることの 1 つです。

于 2012-05-31T09:38:09.603 に答える