如何使用where子句

时间:2019-04-04 08:39:41

标签: sql sql-server join indexing where-clause

我已经搜索了一段时间,但找不到解决“问题”的答案。

我有3个具有以下结构的示例表。

客户:

  • CustomerId
  • 名字
  • 姓氏
  • 性别
  • 已删除

发票:

  • InvoiceId
  • CustomerId
  • 金额
  • 位置
  • IsValid

InvoicePos:

  • InvoicePosId
  • InvoiceId
  • PosName
  • 已付款

现在,我想通过以下查询将它们加入。

SELECT T1.FirstName,
       T1.LastName,
       T2.Amount,
       T3.PosName
FROM Customer AS T1
     JOIN Invoice AS T2 ON T1.CustomerId = T2.CustomerId
     JOIN InvoicePos AS T3 ON T2.InvoiceId = T3.InvoiceId
WHERE T1.FirstName = 'A'
  AND T1.LastName = 'B'
  AND T2.Positions = 3
  AND T3.IsPaid = 1;

对于表Customer,我有一个名字,姓氏,客户编号的索引

对于InvoicePos,我有一个IsPaid,InvoiceId,InvoicePosId的索引

但是表Invoice应该使用什么索引?

5 个答案:

答案 0 :(得分:0)

您还可以对查询运行查询优化器,SQL将为您提供最佳的索引应用,并向您显示性能提高的百分比。

答案 1 :(得分:0)

仅对于这种确切的查询,将表2和Invoice上的索引与CustomerId, Positions一起使用才是理想的。

尽管通常以下索引是有意义的:

Customer:
  unique index on CustomerId
  index on LastName, FirstName
Invoice:
  unique index on InvoiceId
  index on CustomerId
InvoicePos:
  unique index on InvoicePosId
  unique index on InvoiceId, InvoiceId
  index on IsPaid, InvoiceId  (for your scenario)

答案 2 :(得分:0)

使用这些索引:

Create Index IX__Customer_001 on Customer (CustomerId,FirstName,LastName)
Create Index IX__Invoice_001 on Invoice (CustomerId,InvoiceId,Positions) include (Amount)
Create Index IX__InvoicePos_001 on InvoicePos (InvoiceId,IsPaid) include (PosName)

您必须使用仅用作include子句上选择列的字段,并将谓词放在关键列上

答案 3 :(得分:0)

我的主要问题是了解查询的解决顺序。

在AI列上有一些索引(CostumerId,InvoiceId,InvoicePosId)。

表1上的索引(名字,姓氏,CostumerId)是有意义的,因为它可以过滤名称,然后与Invoicetable联接。

但是第二个索引对我来说不清楚。

答案 4 :(得分:0)

对于此查询:

SELECT T1.FirstName, T1.LastName, T2.Amount, T3.PosName
FROM Customer T1 JOIN
     Invoice T2
     ON T1.CustomerId = T2.CustomerId JOIN
     InvoicePos T3
     ON T2.InvoiceId = T3.InvoiceId
WHERE T1.FirstName = 'A' AND
      T1.LastName = 'B' AND
      T2.Positions = 3 AND
      T3.IsPaid = 1;

我建议以下索引:

  • Customer(FirstName, LastName, CustomerId)
  • Invoice(CustomerId, InvoiceId, Positions, Amount)
  • InvoicePost(InvoiceId, IsPaid, PosName)

首先,它们涵盖了查询的索引。因此,仅需要索引。如果SELECT中还有其他列,则可以从索引中删除仅SELECT列。

这个想法是从最有选择性的WHERE条件开始的。我猜想名称限制是最严格的。因此,索引从Customer开始并使用WHERE条件。然后,添加来自ONSELECT子句的其他列。

对于其余表,JOIN列是索引中的第一把关键字,之后是WHERESELECT列。