在使用连接时,我们如何大大优化我们的MySQL数据库(或替换它)?

时间:2010-06-14 20:09:21

标签: mysql database database-design database-optimization

这是我第一次接近极高音量的情况。这是一个基于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)

我的问题:

  1. 是否有像MySQL这样的替代数据库具有JOIN支持,但速度更快? (我知道有Postgre,还在评估它。)

  2. 否则,会启动MySQL实例,将本地数据库加载到内存中并每5分钟重新加载一次?

  3. 否则,有什么方法可以将整个操作切换到Redis或Cassandra,并以某种方式更改JOIN行为以匹配NoSQL的(非JOIN-able)性质?

  4. 谢谢!


    编辑:这里有更多细节:

    具有展平选择的完全执行的SQL(在上面截断):

      

    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

    EXPLAIN /执行计划:

    +----+-------------+-----------+--------+------------------+-------------+---------+------------------------------------+------+----------------------------------------------+
    | 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)
    

2 个答案:

答案 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 小时。然后你的应用程序只会查询辅助表(或者可能与一个经常更改数据的表连接),它可能会更快。