0

我的应用程序中有许多看起来像这样的查询;

SELECT DISTINCT STREET_NUMBER, STREET_NAME
FROM leads
WHERE STREET_NAME || ',' || SUBURB IN (select VAL from streetFilter)
    AND USER_ID IN (%@)
    AND TIMESTAMP >= '%@'
    AND TIMESTAMP <= '%@'
    AND GEO_LAT <> '0'
ORDER BY STREET_NAME, CAST(`STREET_NUMBER` AS SIGNED) ASC

我的问题是,我应该向哪些值或值集添加索引。

到目前为止,我刚刚添加了所有内容,即 CREATE INDEX temp ON 线索('见下文')

  1. (STREET_NUMBER,STREET_NAME)
  2. (街道,郊区)
  3. (STREET_NAME || ',' || 郊区)
  4. (用户身份)
  5. (时间戳)
  6. (GEO_LAT)
  7. (街道、郊区、USER_ID、TIMESTAMP、GEO_LAT)
  8. (STREET_NAME || ',' || SUBURB、USER_ID、TIMESTAMP、GEO_LAT)
  9. (街道名称)
  10. (街道号码)
  11. (演员(STREET_NUMBER已签名))
  12. (STREET_NAME,STREET_NUMBER)
  13. (STREET_NAME,演员(已STREET_NUMBER签名))

但我知道这不可能。谁能指出其中哪些不起作用或不会使我的查询更快,哪些会?

数据库是sqlite

我的创建语句:@“CREATE TABLE IF NOT EXISTS 线索(LEAD_ID BIGINT PRIMARY KEY, USER_ID INTEGER, GEO_LAT, GEO_LONG, CUSTOMER_NAME, UNIT_NUMBER, STREET_NUMBER, STREET_NAME, SUBURB, STATE, POSTCODE INTEGER, NMI, DPI_MIRN, STATUS, STATUS_INT INTEGER, OUTCOME INTEGER, OUTCOME_FULL INTEGER, FINAL_CODE INTEGER, NOTES, NOTES_EXTRA, TIMESTAMP)"];

719130;50;-32.933871;151.774978;Mr David Lee;1;34;LEMNOS PDE;NEWCASTLE;NSW;2300;;;P;0;0;;0;;0:0:0;20120602174036 719233;50;- 32.9307183;151.7803428;Mr Mitch James;1;1-7;TYRRELL ST;THE HILL;NSW;2300;;;P;0;0;;0;;0:0:0;20120602174036 719234;50;-32.933155; 151.777351;Ben Foster 先生;;4;BINGLE ST;NEWCASTLE;NSW;2300;41021027208;52404368858;C;0;0;;0;;0:0:0;20120602174036 719300;50;-32.9291125;151.785025;Mslyn; Rajakulenthiran;U 12;3;KING ST;NEWCASTLE;NSW;2300;;;P;0;0;;0;;0:0:0;20120602174036

查询现在是 SELECT LEAD_ID, USER_ID, UNIT_NUMBER, STREET_NUMBER, STREET_NAME, SUBURB, STATE, POSTCODE, STATUS_INT, OUTCOME, CUSTOMER_NAME, NOTES FROM Leads JOIN resultsFilter ON Leads.OUTCOME = 结果过滤器.VAL JOIN郊区过滤器打开线索.SUBPOST =郊区过滤器.VAL USER_ID IN (%@) AND TIMESTAMP BETWEEN '%@' AND '%@' ORDER BY SUBURB, STREET_NAME, CAST(STREET_NUMBER AS SIGNED)

我最初的情况仍然没有改善。似乎是最慢的顺序

4

3 回答 3

0

最好的办法是查看查询执行计划并检查返回的建议索引。索引过多和/或在错误的位置实际上会损害性能,这会适得其反。

要访问执行计划:

在查询菜单上,单击显示执行计划,然后在查询窗口中运行查询。执行计划和查询结果现在显示在窗口的单独窗格中,因此您可以一起查看它们。

于 2012-08-08T05:37:56.893 回答
0

好吧,您对表中的几乎所有字段都进行了范围扫描。

我建议查看说明,然后查看以下内容是否更好:

create index lookup_idx on leads(user_id, timestamp, geo_lat).

如果您使用的是 MySQL,您将无法使用该索引的 geo_lat 部分,因此请使用 (user_id, timestamp)。Oracle 可以在范围内执行 SKIP SCANS,因此如果使用 Oracle,请将 geo_lat 保留在索引中。

让我们确切地知道您正在使用哪个数据库,并发布 EXPLAIN PLAN(但是您为该 RDBMS 获取它)和潜在客户的 CREATE TABLE 以便我们可以看到发生了什么。

编辑注意到这是 SQLlite。在这种情况下可能是 (user_id, timestamp),但我可以稍后再用 SQLfiddle 检查。

再次,请发布 CREATE TABLE 和一些示例数据。

于 2012-08-08T05:43:09.547 回答
0

一般来说,您只需要(也许)在那些涉及搜索、排序、连接或 WHERE 条件的字段上使用索引。 您的表中有几个字段不属于任何这些类别;可以安全地消除这些字段的索引,而不会对查询的性能产生负面影响。

运行执行计划将告诉您是否也不需要属于这些类别之一的字段的任何索引。例如,如果字段的基数太小(即唯一值很少)以至于索引无济于事,这是可能的。

有关 SQLite 的特定优化和索引使用的更多信息可以在这里找到:http ://www.sqlite.org/optoverview.html 。

值得注意的是:SQLite 将最多为查询中的每个表使用一个索引。请参阅在多个索引之间进行选择。ANALYZE 命令将帮助您确定哪些索引最有价值。

于 2012-08-08T05:43:21.720 回答