Fastest way for this query (What is the best strategy) given a date range

前端 未结 10 2344
半阙折子戏
半阙折子戏 2021-01-02 11:35

I have a table A that has a startDate and an end dateDate as 2 datetime columns besides some more other columns. I have another table B that has one datetime column call it

相关标签:
10条回答
  • 2021-01-02 12:10

    a useful link: Using CROSS APPLY to optimize joins on BETWEEN conditions

    0 讨论(0)
  • 2021-01-02 12:10

    every version of sql server 2000, 2005, 2008 has a program called DataBase tuning advisor when you run some query it tells you what indexes you need to add to get the query faster Best Regards, Iordan

    0 讨论(0)
  • 2021-01-02 12:10

    I'd go with this

    CREATE CLUSTERED INDEX IX_DateRange ON dbo.A
        (
        StartDate,
        EndDate DESC
        ) 
    GO
    
    0 讨论(0)
  • 2021-01-02 12:14

    If you need to optimize try to run this query in the Query Analyzer.

    0 讨论(0)
  • 2021-01-02 12:18

    You need 3 indexes A.startDate, B.dates and A.endDate, may be index (A.endDate+A.startDate) is also good. I have no details on another columns and purposes for these tables, but review possibility to use clustered index.

    In anyway use "Execution plan" option to make decision between all these variants, because my suggestion is too general

    0 讨论(0)
  • 2021-01-02 12:23

    Update:

    See this article in my blog for efficient indexing strategy for your query using computed columns:

    • Efficient date range query: SQL Server

    The main idea is that we just compute rounded length and startDate for you ranges and then search for them using equality conditions (which are good for B-Tree indexes)


    In MySQL and in SQL Server 2008 you could use SPATIAL indexes (R-Tree).

    They are particularly good for the conditions like "select all records with a given point inside the record's range", which is just your case.

    You store the start_date and end_date as the beginning and the end of a LineString (converting them to UNIX timestamps of another numeric value), index them with a SPATIAL index and search for all such LineStrings whose minimum bounding box (MBR) contains the date value in question, using MBRContains.

    See this entry in my blog on how to do this in MySQL:

    • Overlapping ranges: MySQL

    and a brief performance overview for SQL Server:

    • Overlapping ranges: SQL Server

    Same solution can be applied for searching a given IP against network ranges stored in the database.

    This task, along with you query, is another often used example of such a condition.

    Plain B-Tree indexes are not good if the ranges can overlap.

    If they cannot (and you know it), you can use the brilliant solution proposed by @AlexKuznetsov

    Also note that this query performance totally depends on your data distribution.

    If you have lots of records in B and few records in A, you could just build an index on B.dates and let the TS/CIS on A go.

    This query will always read all rows from A and will use Index Seek on B.dates in a nested loop.

    If your data are distributed other way round, i. e. you have lots of rows in A but few in B, and the ranges are generally short, then you could redesign your tables a little:

    A
    
    start_date interval_length
    

    , create a composite index on A (interval_length, start_date)

    and use this query:

    SELECT  *
    FROM    (
            SELECT  DISTINCT interval_length
            FROM    a
            ) ai
    CROSS JOIN
            b
    JOIN    a
    ON      a.interval_length = ai.interval_length
            AND a.start_date BETWEEN b.date - ai.interval_length AND b.date
    
    0 讨论(0)
提交回复
热议问题