Does a multi-column index work for single column selects too?

后端 未结 3 2039
被撕碎了的回忆
被撕碎了的回忆 2020-12-29 01:22

I\'ve got (for example) an index:

CREATE INDEX someIndex ON orders (customer, date);

Does this index only accelerate queries where cust

相关标签:
3条回答
  • 2020-12-29 01:56

    I'm pretty sure this will work, yes - it does in MS SQL Server anyway.

    However, this index doesn't help you if you need to select on just the date, e.g. a date range. In that case, you might need to create a second index on just the date to make those queries more efficient.

    Marc

    0 讨论(0)
  • 2020-12-29 02:04

    marc_s has the correct answer to your first question. The first key in a multi key index can work just like a single key index but any subsequent keys will not.

    As for how much faster the composite index is depends on your data and how you structure your index and query, but it is usually significant. The indexes essentially allow Sqlite to do a binary search on the fields.

    Using the example you gave if you ran the query:

    SELECT * from orders where customer > 33 && date > 99
    

    Sqlite would first get all results using a binary search on the entire table where customer > 33. Then it would do a binary search on only those results looking for date > 99.

    If you did the same query with two separate indexes on customer and date, Sqlite would have to binary search the whole table twice, first for the customer and again for the date.

    So how much of a speed increase you will see depends on how you structure your index with regard to your query. Ideally, the first field in your index and your query should be the one that eliminates the most possible matches as that will give the greatest speed increase by greatly reducing the amount of work the second search has to do.

    For more information see this: http://www.sqlite.org/optoverview.html

    0 讨论(0)
  • 2020-12-29 02:04

    I commonly use combined indexes to sort through data I wish to paginate or request "streamily".

    Assuming a customer can make more than one order.. and customers 0 through 11 exist and there are several orders per customer all inserted in random order. I want to sort a query based on customer number followed by the date. You should sort the id field as well last to split sets where a customer has several identical dates (even if that may never happen).

    sqlite> CREATE INDEX customer_asc_date_asc_index_asc ON orders
              (customer ASC, date ASC, id ASC);
    

    Get page 1 of a sorted query (limited to 10 items):

    sqlite> SELECT id, customer, date FROM orders
              ORDER BY customer ASC, date ASC, id ASC LIMIT 10;
    
    2653|1|1303828585
    2520|1|1303828713
    2583|1|1303829785
    1828|1|1303830446
    1756|1|1303830540
    1761|1|1303831506
    2442|1|1303831705
    2523|1|1303833761
    2160|1|1303835195
    2645|1|1303837524
    

    Get the next page:

    sqlite> SELECT id, customer, date FROM orders WHERE
              (customer = 1 AND date = 1303837524 and id > 2645) OR
              (customer = 1 AND date > 1303837524) OR
              (customer > 1)
              ORDER BY customer ASC, date ASC, id ASC LIMIT 10;
    
    2515|1|1303837914
    2370|1|1303839573
    1898|1|1303840317
    1546|1|1303842312
    1889|1|1303843243
    2439|1|1303843699
    2167|1|1303849376
    1544|1|1303850494
    2247|1|1303850869
    2108|1|1303853285
    

    And so on...

    Having the indexes in place reduces server side index scanning when you would otherwise use a query OFFSET coupled with a LIMIT. The query time gets longer and the drives seek harder the higher the offset goes. Using this method eliminates that.

    Using this method is advised if you plan on joining data later but only need a limited set of data per request. Join against a SUBSELECT as described above to reduce memory overhead for large tables.

    0 讨论(0)
提交回复
热议问题