用于优化查询的sql索引
我在我的应用程序中有许多类似这样的查询用于优化查询的sql索引,sql,ios,sqlite,indexing,Sql,Ios,Sqlite,Indexing,我在我的应用程序中有许多类似这样的查询 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 <>
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
我的问题是,我应该向哪些值或值集添加索引
到目前为止,我刚刚添加了所有内容,即在Lead上创建INDEX temp“见下文”
街道号码、街道名称
郊区街道
街道名称,郊区
用户ID
时间戳
地拉特
街道、郊区、用户ID、时间戳、地理位置
街道名称、郊区、用户ID、时间戳、地理位置
街道名称
街道号码
已签名的Castu编号
街道名称、街道编号
签名的街道名称、街道编号
但我知道这不可能是对的。
有人能指出其中哪些不起作用,或者不会使我的查询更快,哪些会
数据库是sqlite
我的create语句:
@创建表格如果不存在leads LEAD_ID BIGINT主键、USER_ID INTEGER、GEO_LAT、GEO_LONG、CUSTOMER_NAME、UNIT_NUMBER、STREET_NUMBER、STREET_NAME、郊区、州、邮政编码整数、NMI、DPI_MIRN、STATUS、STATUS_INT INTEGER、Output_FULL INTEGER、FINAL_CODE INTEGER、NOTES、NOTES_EXTRA、TIMESTAMP]
719130;50;-32.933871;151.774978;李国宝先生,;1.34;LEMNOS-PDE;纽卡斯尔新南威尔士州;2300;;;P0;0;;0;;0:0:0;20120602174036
719233;50;-32.9307183;151.7803428;詹姆士先生,;1.1-7;泰瑞尔街;小山;新南威尔士州;2300;;;P0;0;;0;;0:0:0;20120602174036
719234;50;-32.933155;151.777351;本福斯特先生;;4.宾格尔街;纽卡斯尔新南威尔士州;2300;41021027208;52404368858;C0;0;;0;;0:0:0;20120602174036
719300;50;-32.9291125;151.785025;Marilyn Rajakulenthiran女士;u12;3.国王街;纽卡斯尔新南威尔士州;2300;;;P0;0;;0;;0:0:0;20120602174036
查询现在是选择LEAD_ID、USER_ID、UNIT_NUMBER、STREET_NUMBER、STREET_NAME、郊区、州、邮政编码、STATUS_INT、Output、CUSTOMER_NAME、LEAD上LEAD JOIN outcomeFilter的备注。OUTCOME=outcomeFilter.VAL加入LEAD上的suburbFilter。SUBPOST=suburbFilter.VAL,其中用户ID在%@中,时间戳在“@”和“@”之间,按郊区排序,签名的街道名称、街道编号
还是没有改善我的初始状态。这似乎是最慢的顺序。最好的做法是查看查询执行计划并检查返回的建议索引。索引太多和/或在错误的位置实际上会损害性能,这会适得其反 要访问执行计划,请执行以下操作: 在“查询”菜单上,单击“显示执行计划”,然后运行查询 在查询窗口中。执行计划和查询结果现在显示在 将窗口的窗格分开,以便您可以一起查看它们
你对表中几乎所有的字段都进行了范围扫描 我建议看一下解释,然后看看下面是否能让它更好:
create index lookup_idx on leads(user_id, timestamp, geo_lat).
如果您使用的是MySQL,您将无法使用该索引的geo_lat部分,因此请使用user_id,timestamp。Oracle可以跳过扫描范围,因此如果使用Oracle,请在索引中保留geo_lat
让我们确切地知道您使用的是哪一个数据库,并发布解释计划(无论您是如何获取该RDBMS的计划)和Lead的创建表,以便我们可以看到发生了什么
编辑注意到这是SQLlite。可能是用户id,在这种情况下是时间戳,但我可以稍后使用SQLFIDLE进行检查
同样,请发布创建表和一些示例数据。一般来说,您只需要搜索、排序、连接或WHERE条件所涉及的字段上的索引。表中有几个字段不属于这些类别;可以安全地删除这些字段的索引,而不会对查询的性能产生负面影响 运行执行计划将告诉您是否也不需要属于这些类别的字段的任何索引。例如,如果字段的基数太小,即索引没有帮助的唯一值非常少,则这是可能的 有关SQLite特定优化和索引使用的更多信息,请参见:
值得注意的是:SQLite将为查询中的每个表最多使用一个索引。看见“分析”命令将帮助您确定哪些索引最有价值。我敢打赌,通过将该子选择重写为联接,您将获得一些改进。很抱歉,这次没有。我的查询现在是选择LEAD_ID、USER_ID、UNIT_NUMBER、STREET_NUMBER、STREET_NAME、郊区、州、邮政编码、STATUS_INT、Output、CUSTOMER_NAME、LEAD上LEAD JOIN outcomeFilter的备注。OUTCOME=outcomeFilter.VAL加入LEAD上的suburbFilter。SUBPOST=suburbFilter.VAL,其中用户ID在%@中,时间戳在“@”和“@”之间,按郊区排序,签名的街道名称、街道编号。我还尝试添加更多的索引,但仍然没有开始时快。我认为很多问题都是因为最后的订货。有什么想法吗?运行此查询的执行计划只会告诉您索引在何处有助于此查询,而不会告诉您其他查询,而且它不会影响spea
k到其他事情,如插入成本。@RobertHarvey-正确。根据问题标题和OP声明,他创建了一个关于所有内容的索引,我的重点是索引。我已经完成了执行计划,但我不知道这意味着什么。我得到了addr、opcode、p1、p2、p3、p4、p5、注释列和134行,但无法理解itI尝试使用BETWEEN作为时间戳的意义,但它似乎使它变慢了。我可以从中使用其他哪些字段,或者适合哪些字段?