SQL表设计可实现最佳性能

时间:2019-02-06 09:39:23

标签: sql-server query-performance

我正在设计一个MVC asp.net Web App来管理数家餐厅的预订。

我主要关心的是当用户希望获得特定日期,特定餐厅的所有预订时的数据库性能。

我有一张表,其中包含以下列/数据类型:

  • [Id]-int
  • [RestaurantId]-int
  • [StartDateTime]-日期时间
  • [ServiceDuration]-int
  • [WorkerId]-nvarchar(128)
  • [ServiceId]-int
  • [CostumerId]-int
  • [Notes]-nvarchar(128)

我试图找出是否只有这样一个表(可以包含大量行)是最好的数据库设计方法

一种选择是让第二个表仅包含查询所需的列,因为我在SO上读到,具有较少列的表比具有较多列的表要好:

  • [Id]-int
  • [RestaurantId]-int
  • [StartDateTime]-日期时间
  • [BookingId]-int(指向第一张桌子上的预订ID)

3 个答案:

答案 0 :(得分:0)

我认为the design of the table is normalized一切正常。您可以做的只是为字段StartDateTime编写覆盖索引,如下所示:

CREATE NONCLUSTERED INDEX [IX_YourTable_StartDateTime_RestaurantId_BookingId_Id  ]
ON dbo.YourTable
(StartDateTime, RestaurantId, BookingId, Id)
GO

有了该索引,当您编写所需的查询时,您的查询计划中就会有寻求索引

Select 
  RestaurantId
, BookingId
, Id
YourTable
WHERE StartDateTime = '...'

请特别注意索引中列的顺序 (StartDateTime, RestaurantId, BookingId, Id)。如果将StartDateTime移到NOT的第一位置,则将没有索引查找。

答案 1 :(得分:0)

一张桌子很好。

如果您只需要每日预订报告中的4个字段,则将它们仅包含在sql的SELECT子句中,以便仅将相关字段返回给您,从而最大程度地缩短了转移给您的日期。

答案 2 :(得分:0)

您的场景是最标准的带有联结表的三表设计方案。我建议为餐厅和预订使用两个表格:

Restaurant
    id
    name
    type
    notes

Booking
    id
    date

然后,创建第三个 junction 表,该表将餐厅与其预订相关联:

RestaurantBooking
    restaurant_id
    booking_id
    PK (restaurant_id, booking_id)

这是一种规范化的方法,它使您可以有效地存储餐厅预订,而无需重复关系两边的元数据。

要查找指定餐厅的所有预订,您可以尝试:

SELECT b.*
FROM Booking b
INNER JOIN RestaurantBooking rb
    ON b.id = rb.booking_id
INNER JOIN Restaurant r
    ON rb.restaurant_id = r.id
WHERE
    r.name = 'Tavern on the Green' AND
    b.date = CAST(GETDATE() AS date);