由于MySQL数据库的规范化,我遇到了一些性能问题。
我的大多数使用数据库的应用程序需要做一些沉重的嵌套查询,这在我的情况下花费了很多时间。对于索引,查询可能需要2秒来运行。无索引约45秒
几个月前我遇到的一个解决方案是使用一个更快、更线性的基于文档的数据库,在我的例子中是Solr,作为主数据库。一旦MySQL数据库中有什么变化,Solr就会被通知。
这真的很有效。使用Solr数据库的所有查询仅花费3ms。
数字看起来不错,但是我遇到了一些问题。
MySQL数据库约200mb, Solr数据库约1.4Gb。每次我需要更改一个表/列时,数据库需要重新索引,在这个例子中花费了12个多小时。
- 很难同时渲染Solr对象和Active Record (MySQL)对象而不被弄湿。
视图依赖于某个对象。它不关心对象本身是一个活动记录对象还是一个Solr对象,只要它可以调用它的一组属性。
。
# Controller
@song = Song.first
# View
@song.artist.urls.first.service.name
在我的例子中,问题是从Solr返回的数据是这样平坦的。
{
id: 123,
song: "Waterloo",
artist: "ABBA",
service_name: "Groveshark",
urls: ["url1", "url2", "url3"]
}
这迫使我构建一个可以传递给视图的活动记录对象。
我的问题
有更好的方法来解决这个问题吗?能够快速处理复杂查询的某种超级超级快速的主只读数据库将是不错的选择。
Solr单个字段更新
关于在模式更改时重新索引:Solr还不支持更新单个字段,但是有一个关于这个的JIRA问题仍然没有解决。但是,您要更改多少次模式呢?
MongoDB
如果你可以没有RDBMS(没有连接,模式,事务,外键约束),一个基于文档的数据库,如MongoDB,或CouchDB将是一个完美的选择。(这里有一个很好的比较)
为什么使用MongoBD:
- 数据是原生格式的(您可以直接在视图中使用像Mongoid这样的ORM映射器,因此您不需要像使用Solr那样调整您的记录) 动态查询
- 在非全文搜索查询上有很好的性能
- 无模式(不需要迁移)
- 内置,易于设置复制
为什么使用SOLR:
- 高级,非常高性能的全文搜索
为什么使用MySQL
- 连接、约束、事务
解决方案
所以,解决方案(组合)将是:
使用MongoDB + Solr
- ,但你仍然需要重新索引所有的模式更改
只使用MongoDB
- 但是放弃对高级全文搜索的支持
使用MySQL在主从配置,并平衡读取从(s)(使用一个插件,如octupus) + Solr
- <
- 设置复杂性/gh>
保持当前设置,在MySQL中反规范化数据
- 的
Solr索引速度慢
MySQL数据库约200mb, Solr数据库约1.4Gb数据。每次我需要更改数据库需要的表/列驯鹿驯鹿,在这个例子中花了超过12个小时。
在Solr中重新索引200MB DB 不应该花12个小时!很可能您还有其他问题,如:
MySQL:- n+1 issue
SOLR:
- 每次请求后提交-这是默认设置,你使用一个插件,如太阳黑子,但它是一个完美杀手的生产
:
- 默认情况下,Sunspot::Rails在每个请求结束时提交更新Solr索引。把它关掉。
中配置使用Solr的自动提交功能。在solr/conf/solrconfig.xml
- 是为假定的不一致感到高兴。不要在需要搜索结果的地方使用搜索是即时的。
- 其他设置问题(http://wiki.apache.org/solr/SolrPerformanceFactors#Indexing_Performance)
查看日志查看更多细节
与其将数据推送到Solr中以平面化记录,不如在MySQL数据库中创建一个单独的表,该表针对只读访问进行了优化。
你似乎自相矛盾
视图依赖于某个对象。它不关心对象本身是一个活动记录对象还是一个Solr对象,只要它可以调用它的一组属性。
在我的情况下的问题是,从Solr返回的数据是平坦的…这迫使我构建一个可以由视图呈现的假活动记录对象。