Sql 存储大城市以便自动完成查询的最佳方式是什么?

Sql 存储大城市以便自动完成查询的最佳方式是什么?,sql,amazon-s3,indexing,Sql,Amazon S3,Indexing,我有一份城市名单,大约2712406条记录。每个都有状态代码,用户首先选择状态代码 状态代码和名称都已编制索引。 我当前对数据库的查询以/cities?code=[StateCode]&name=[Alphabets] 内部转换为 return db.Cities.Where(x=>x.StateCode == stateCode && x.Name.StartsWith(name)) .OrderBy( x=> x.Name )

我有一份城市名单,大约2712406条记录。每个都有状态代码,用户首先选择状态代码

状态代码和名称都已编制索引。

我当前对数据库的查询以
/cities?code=[StateCode]&name=[Alphabets]

内部转换为

return db.Cities.Where(x=>x.StateCode == stateCode && x.Name.StartsWith(name))
                .OrderBy( x=> x.Name )
                .Take(10);
当数据库忙着执行更大的操作时,此查询会超时

我想到了两种方法

  • 在AmazonS3上存储预先配置的查询
  • 将StateCode和Name合并为一列,并执行SearchName.StartWith(StateCode+“/”+Name)
  • 存储S3对象

    我计算出用户需要的组合总数是1000万。因此,假设5KB的JSON只用于检索前10个城市。它需要50GB的存储空间。大约每月5美元左右。这很好,但如果我将json存储为
    /stateCode/a/stateCode/b
    等,那么使用CDN的用户会更快地使用它吗

    结合州和市密钥

    假设我有一个单独的列,并将其组合和索引为“StateCode/Name”。
    在这里我知道查询将命中索引的B+树。在一列索引上进行查找会有更大的好处吗?或者它会和当前查询几乎相同吗?我最好使用S3。我不知道S3是否能提供与DB相同的性能,我所能做的就是在我的每个应用程序服务器中设置多个只读DB。

    关于在SQL DB中组合状态键和城市键:如果将列分开,也可以使用B+树索引。您只需要使用[组合的|串联的|多列]索引。例如

    CREATE INDEX blah ON cities (statecode, name);
    
    注意:一个索引包含两列。与非精确运算符(
    StartWith
    而不是equals)一起使用的列位于最后

    如果StartWith方法转换为类似SQL的SQL,则此索引支持您的查询:

    SELECT name
      FROM cities
     WHERE state = ?
       AND name LIKE 'b%'
    
    如果以另一种方式实现
    StartsWith
    ,则可能需要调整以获得适当的响应时间。最好是打开SQL查询日志记录并查看一下。您的ORM工具很可能会将
    StartsWith
    转换为无法正确使用此索引的内容,但这可能很容易解决,因此它工作得很好(也很快)

    ps:您使用的是“take(10)”,而没有使用(sql)命令,这会产生未定义的结果


    pps:我觉得S3的想法也很有趣;)

    结果表明,组合文本索引效果良好。连接是昂贵的操作

  • 创建列CityPath=StateCode+'/'+CityName
  • 索引城市路径
  • 对于两个不同的结果集,查询的性能优于AND

    @CityPath = StateCode + '/' + CharactersTyped + '%'
    SELECT TOP 10 * FROM Cities WHERE CityPath LIKE @CityPath
    
    在上面的查询中,B+索引必须搜索有限的子树,因为StateCode本身就是根。但是在下面的查询中,B+索引必须搜索更大的子树,并且必须比较每个结果的状态代码等效性。在第二个查询中,CityName搜索的B+索引扫描结果集较大,这导致微秒超时

    @StateCode = StateCode
    @CityName = CharactersTyped    
    SELECT TOP 10 * FROM Cities WHERE CityName LIKE @CityName
         AND StateCode = @StateCode
    

    如果数据存在于如上所示的层次结构中,则计算列索引可以改进数据搜索。

    @dasblinkenlight当然是的,我刚刚更新了代码。我已经为两列编制了索引。我已经更新了我的问题。我也在做OrderBy,我只是写了一些代码,但是实际的查询有OrderBy和Take两个。@AkashKava那么您还有什么问题?应该使用索引(如果您在两个列上都有一个索引,如上所示,也可以按如上所示的顺序使用),并且它可能足够快。如果没有使用,请记录SQL查询并显示给我们。两个索引都在查询计划中使用,问题是单个索引的性能会优于S3?@AkashKava单个索引的性能肯定会优于两个索引,可能是一个数量级!也许已经足够好了。然而,与S3相比,这一想法很难实现。请记住,S3还需要某种看起来与我上面建议的索引非常相似的索引。感谢您的回答,我通过创建一个计算列并在其上创建索引来解决此问题。出于好奇:您确定在测试中按此顺序在两个列(statecode、cityname)上使用了单个索引吗?嗯,然后,它的性能应该与您的解决方案大致相同。但是,您对computed列很满意,为什么不呢?这两列上的索引都超时了。到目前为止,计算列未超时。