我们有一个运动购物网站,可以向用户推荐产品。我们的查询通过对以下效果的三个表进行 JOIN 来推荐:(1) 用户对什么运动感兴趣,(2) 什么产品是该运动的一部分,以及 (3) 消除用户已经购买的产品。我们目前有三张 table 。响应时间为 3 秒。
为了使查询响应更快,我们建议将两个表合并为一个表。所附图片显示了建议的逻辑。我的问题是:
我们在 AWS MySQL RDS 上。所有索引都已正确完成。请不要讨论迁移到 Redis、MEMSql 等,我只是想在这个阶段了解建议的逻辑是否会更快。
谢谢你的帮助!!
创建
CREATE TABLE UserPreferences (
UserPreferenceId int(11) NOT NULL AUTO_INCREMENT,
UserId int(11) NOT NULL,
FamilyId int(11) NOT NULL,
InsertedDate datetime NOT NULL,
PRIMARY KEY (UserPreferenceId),
KEY userID (UserId),
KEY FamilyId (FamilyId),
KEY user (UserId),
KEY fk_UserPreferences_1 (FamilyId),
) ENGINE=InnAoDB AUTO_INCREMENT=261 DEFAULT CHARSET=utf8
CREATE TABLE ArticleToFamily (
ArticleToFamilyId int(10) unsigned NOT NULL AUTO_INCREMENT,
ArticleId int(11) DEFAULT NULL,
FamilyId int(11) unsigned NOT NULL,
InsertedDate datetime DEFAULT NULL,
Confidence int(11) NOT NULL DEFAULT '0',
Rank int(11) NOT NULL DEFAULT '0',
PRIMARY KEY ArticleToFamilyId),
KEY ArticleIdAndFamilyId` (ArticleId,FamilyId),
KEY FamilyId (FamilyId)
) ENGINE=InnoDB AUTO_INCREMENT=19795572 DEFAULT CHARSET=latin1
CREATE TABLE ItemsUserHasBought (
ItemsUserHasBoughtId int(11) NOT NULL AUTO_INCREMENT,
UserId int(11) NOT NULL,
ArticleId int(11) NOT NULL,
BuyDate datetime NOT NULL,
InsertedDate datetime NOT NULL,
UpdatedDate datetime NOT NULL,
Status char(1) NOT NULL DEFAULT '1',
PRIMARY KEY (ItemsUserHasBoughtId),
KEY ArticleId (ArticleId)
) ENGINE=InnoDB AUTO_INCREMENT=367 DEFAULT CHARSET=latin1
最佳答案
不要这样做。
组合表通常意味着某种非规范化,这不是您希望在关系数据库中移动的方向。它很少没有副作用,而且常常无法达到预期的效果。总而言之,只有在所有其他途径都用尽时才能避免的事情。
相反,检查您拥有的三个表的索引。很可能在正确的位置添加一个外键可以很容易地使这个查询在当前时间的一小部分内运行。不幸的是,在我们知道您已经在使用哪些索引之前,我们无法更具体地说明如何改进它。也有可能您在这里做了正确的事情,并且在您的服务器能够执行的操作方面确实碰壁了……但可能不会。
如果索引没有帮助,我通常会看的下一个地方是物化/索引 View 。 Sql Server、Oracle、Postgresql 和大多数其他现代数据库服务器引擎都支持这一点。遗憾的是,像窗口函数、APPLY/横向连接操作和正确的 NULL 处理一样,索引 View 是 ansi sql 的许多部分之一,而 MySql 落后于其他数据库。遗憾的是,随着时间的推移,MySql 越来越成为一个笑话……但这可能是甲骨文自收购 Sun 以来计划的全部内容。如果你真的想要一个开源数据库,Postgresql 多年来在几乎所有类别中都超过了 MySql。 MySql 现在依靠它的旧势头生活;它很受欢迎,因为它一直很受欢迎,因此在低成本网络主机中广泛可用,但根本不是因为它更好。
不要误会我的意思:MySql 曾经是一个很棒的选择。 Postgresql 几乎不存在,当时 Oracle 和 Sql Server 也好不到哪里去,而且价格对于大多数小企业来说也是遥不可及的。但是 Oracle、Sql Server、Postgresql 和其他公司都在以 MySql 没有的方式前进。具体而言,Postgresql 变得更易于管理,而 MySql 失去了一些赋予其优势的简单性,但没有获得足够的真正重要的功能。
但是任何人都可以成为扶手椅建筑师,而我已经发表过多的社论了。无论如何,鉴于批发数据库更改现在不太可能成为您的选择,请仔细查看您的索引。这是一个很好的赌注,你将能够以这种方式解决你的问题。如果你做不到,你总是可以在你的服务器上投入更多的硬件。因为 MySql 更便宜,对吧?
关于mysql - 通过组合表来增加 JOIN 查询响应时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36523881/
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是
我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我是Google云的新手,我正在尝试对其进行首次部署。我的第一个部署是RubyonRails项目。我基本上是在关注thisguideinthegoogleclouddocumentation.唯一的区别是我使用的是我自己的项目,而不是他们提供的“helloworld”项目。这是我的app.yaml文件runtime:customvm:trueentrypoint:bundleexecrackup-p8080-Eproductionconfig.ruresources:cpu:0.5memory_gb:1.3disk_size_gb:10当我转到我的项目目录并运行gcloudprevie