这是我第一次接近极高音量的情况。这是一个基于MySQL的广告服务器。但是,使用的查询包含大量JOIN,通常只是慢。 (这是Rails ActiveRecord,顺便说一句)
sel = Ads.find(:all,:select =>'*',:joins =>“在ads.campaign_id = campaigns.id上加入广告系列。在营运时加入用户.user_id = users.id LEFT JOIN国家/地区ON countries.campaign_id = campaigns.id LEFT JOIN关键字ON keywords.campaign_id = campaigns.id“,:conditions => [flashstr +”keywords.word =?AND ads.format =?AND campaigns.cenabled = 1 AND(countries .country IS NULL或countries.country =?)AND ads.enabled = 1 AND campaigns.dailyenabled = 1 AND users.uenabled = 1“,kw,format,viewer ['country'] [0]],:order =&gt ; order,:limit => limit)
我的问题:
是否有像MySQL这样的替代数据库具有JOIN支持,但速度更快? (我知道有Postgre,还在评估它。)
否则,会启动MySQL实例,将本地数据库加载到内存中并每5分钟重新加载一次?
否则,有什么方法可以将整个操作切换到Redis或Cassandra,并以某种方式更改JOIN行为以匹配NoSQL的(非JOIN-able)性质?
谢谢!
SELECT campaigns.id,campaigns.guid,campaigns.user_id,campaigns.dailylimit,campaigns.impressions,campaigns.cenabled,campaigns.dayspent,campaigns.dailyenabled,campaigns.fr,ads.id,ads.guid,ads。 user_id,ads.campaign_id,ads.format,ads.enabled,ads.datafile,ads.data1,ads.data2,ads.originalfilename,ads.aid,ads.impressions,countries.id,countries.guid,countries.campaign_id, countries.country,keywords.id,keywords.campaign_id,keywords.word,keywords.bid FROM
ads
加入广告系列广告.campaign_id = campaigns.id加入广告系列。广告活动.user_id = users.id LEFT JOIN国家/地区ON国家/地区.campaign_id = campaigns.id LEFT JOIN关键字ON keywords.campaign_id = campaigns.id WHERE(keywords.word ='design'AND ads.format = 10 AND campaigns.cenabled = 1 AND(countries.country IS NULL OR countries.country = 82)AND ads.enabled = 1 AND campaigns.dailyenabled = 1 AND users.uenabled = 1 AND ads.datafile!='')ORDER BY keywords.bid DESC LIMIT 1,1
+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
| 1 | SIMPLE | keywords | ref | campaign_id,word | word | 257 | const | 9 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | ads | ref | campaign_id | campaign_id | 4 | e_development.keywords.campaign_id | 8 | Using where |
| 1 | SIMPLE | campaigns | eq_ref | PRIMARY | PRIMARY | 4 | e_development.keywords.campaign_id | 1 | Using where |
| 1 | SIMPLE | users | eq_ref | PRIMARY | PRIMARY | 4 | e_development.campaigns.user_id | 1 | Using where |
| 1 | SIMPLE | countries | ALL | campaign_id | NULL | NULL | NULL | 4 | Using where |
+----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
(这是在一个开发数据库中,它没有与生产版本一样多的行。)
ads -> id (primary, autoinc) + aid (unique) + campaign_id (index) + user_id (index)
campaigns -> id (primary, autoinc) + user_id (index)
countries -> id (primary, autoinc) + campaign_id (index) + country (index) + user_id (index)
keywords -> id (primary, autoinc) + campaign_id (index) + word (index) + user_id (index)
user -> id (primary, autoinc)
答案 0 :(得分:3)
存在数据库理论和名义实践,为大多数案例提供框架。并非每个数据库使用模式都完全符合第三范式。因此NoSQL的出现。这些数据库在大多数情况下效果不佳,但在特定情况下效果很好。他们运作良好的一个原因是因为他们不像普通的RDBMS那样工作。 Cassandra确实有一些“加入”设施,但我不记得确切的细节。如果你想快速了解我会推荐Digg开发者博客。有一个很简单的描述。
问题在于我敢打赌你加入4个表会比mySQL慢。确定的唯一方法是学习新的DBMS,安装它,调整安装以及调整MySQL和设置所有数据......你会发现MySQL确实非常好
试图解决EXACT SAME问题,使用不同引擎的EXACT SAME方式不会削减它......你必须像NoSQL开发人员一样思考,而不是使用NoSQL的RDBMS开发人员。
但你可以像沮丧所暗示的那样思考这个问题。
为什么我们有第三范式?易于更新主要是。我更新了一行而不是几十行。它还有助于约束数据,如果我仔细控制国家/地区表中国家/地区的添加,我将永远不会在广告系列表格中出现问题。之后,3NF不会更快地进行查询,这就是我们发明报告数据库,OLAP,Cubes,Star Schema的原因。
关键是报告与编辑/捕获的结构不同。
正如Frustrated所说,确定基础数据的变化速度。如果你真的每5分钟添加一次国家,我会惊呆了。活动吗?可能偶尔?广告?一天几次。构建一个完全展平的表并将其编入索引需要多长时间?这会产生多少行?如果周期时间比你的更新频率短得多......那就建立并查看。测试查询速度。这是一个比购买全新数据库更便宜的实验。
答案 1 :(得分:1)
您是否分析过执行计划?你有没有分析过指数?
我的第一个猜测是,您需要campaigns
的{{1}}索引,user_id
的{{1}}索引,countries
campaign_id
也许是其他人。您需要获取执行计划以查看您的查询正在执行的操作。
另一种选择:此结果集中的数据多久更改一次?分钟?小时?天?如果它是每天或每小时(好几个小时),那么最好有一个包含此结果集的所有列(或只是不太可能经常更改的列)的辅助表,并由此查询填充每 n 小时。然后你的应用程序只会查询辅助表(或者可能与一个经常更改数据的表连接),它可能会更快。