我看到一篇关于 Join 分解的文章。
场景 #1(不好):
Select * from tag
Join tag_post ON tag_post.tag_id=tag.id
Join post ON tag_post.post_id=post.id
Where tag.tag='mysql'
场景 #2(良好):
Select * from tag where tag='mysql'
Select * from tag_post Where tag_id=1234
Select * from post where post.id in (123,456,9098,545)
由于许多原因,特别是缓存,建议坚持方案 #2。 问题是如何加入我们的应用程序内部。你能给我们一个PHP的例子吗 在单独检索它们之后? (我读过 MyISAM Performance: Join Decomposition? 但它没有帮助)
最佳答案
您可以使用 SQL 子选择(如果我理解您的问题)。使用 PHP 会很奇怪,而 SQL 具有所有功能。
SELECT *
FROM `post`
WHERE `id` IN (
SELECT `post_id`
FROM `tag_post`
WHERE `tag_id` = (
SELECT `tag_id`
FROM `tag`
WHERE `tag` = 'mysql'
)
)
我不确定您的数据库结构如何,但这应该可以帮助您入门。这几乎是 SQL 的开始。查询中的查询。您可以使用子选择的结果来选择数据。
在复制此 SQL 并告诉我它不起作用之前,请验证所有表和列的名称。
在任何人开始提示速度、缓存和效率之前:我认为这是相当高效的。无需选择所有数据并使用 PHP 循环遍历它,您只需使用 native SQL 选择较小的位即可。
同样,我强烈反对使用 PHP 获取特定数据。 SQL 就是您所需要的。
编辑:这是你的脚本
假设您有一些包含所有数据的多维数组:
// dummy results
// table tag
$tags = array(
// first record
array(
'id' => 0,
'tag' => 'mysql'
),
// second record
array(
'id' => 1,
'tag' => 'php'
)
// etc
);
// table tag_post
$tag_posts = array(
// first record
array(
'id' => 0,
'post_id' => 0, // post #1
'tag_id' => 0 // has tag mysql
),
// second record
array(
'id' => 1,
'post_id' => 1, // post #2
'tag_id' => 0 // has tag mysql
),
// second record
array(
'id' => 2,
'post_id' => 2, // post #3
'tag_id' => 1 // has tag mysql
)
// etc
);
// table post
$posts = array(
// first record
array(
'id' => 0,
'content' => 'content post #1'
),
// second record
array(
'id' => 1,
'content' => 'content post #2'
),
// third record
array(
'id' => 2,
'content' => 'content post #3'
)
// etc
);
// searching for tag
$tag = 'mysql';
$tagid = -1;
$postids = array();
$results = array();
// first get the id of this tag
foreach($tags as $key => $value) {
if($value['tag'] === $tag) {
// set the id of the tag
$tagid = $value['id'];
// theres only one possible id, so we break the loop
break;
}
}
// get post ids using the tag id
if($tagid > -1) { // verify if a tag id was found
foreach($tag_posts as $key => $value) {
if($value['tag_id'] === $tagid) {
// add post id to post ids
$postids[] = $value['post_id'];
}
}
}
// finally get post content
if(count($postids) > 0) { //verify if some posts were found
foreach($posts as $key => $value) {
// check if the id of the post can be found in the posts ids we have found
if(in_array($value['id'], $postids)) {
// add all data of the post to result
$results[] = $value;
}
}
}
如果您查看上面脚本的长度,这正是我坚持使用 SQL 的原因。
现在,我记得,您想使用 PHP 来加入,而不是用 SQL 来完成。这不是连接,而是使用一些数组获取结果。我知道,但与让所有结果保持原样相比,加入只会浪费时间,而且效率较低。
编辑:21-12-12 作为以下评论的结果
我做了一些基准测试,结果非常惊人:
DATABASE RECORDS:
tags: 10
posts: 1000
tag_posts: 1000 (every post has 1 random tag)
Selecting all posts with a specific tag resulted in 82 records.
SUBSELECT RESULTS:
run time: 0.772885084152
bytes downloaded from database: 3417
PHP RESULTS:
run time: 0.086599111557
bytes downloaded from database: 48644
Please note that the benchmark had both the application as the database on the
same host. If you use different hosts for the application and the database layer,
the PHP result could end up taking longer because naturally sending data between
two hosts will take much more time then when they're on the same host.
即使 subselect 返回的数据少得多,请求的持续时间却长了近 10 倍...
我从来没有预料到这些结果,所以我确信并且当我知道性能很重要时我一定会使用这些信息,但是我仍然会使用 SQL 进行较小的操作嘿嘿...
关于php - 在 PHP 中加入分解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8573747/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
我有一个外部文件:path_to_external_file.rb带有一些类定义:classAsome_definitionsend我想在模块B中加载它,以便上面定义的类A可以称为B::A。我试过:classBload('path_to_external_file.rb')end但是A是在主环境中定义的,而不是在B中定义的:A#=>AB.constants#=>[]如何在某些类/模块中加载外部文件?编辑我是否应该将外部文件作为字符串读取,并在Class.new{...}中评估它们,然后在B中include该类? 最佳答案 你不能。至
这个让我抓狂。我可以通过irb加载gem:steve@server:/var/www/listings$irbirb(main):001:0>Gem.path=>["/home/steve/.gem/ruby/1.9.1","/usr/local/ruby/lib/ruby/gems/1.9.1"]irb(main):002:0>require'nokogiri'=>true但我无法通过Rails控制台加载它:irb(main):001:0>Gem.path=>["/home/steve/.gem/ruby/1.9.1","/usr/local/ruby/lib/ruby/gems/1
我正在使用YAML文件来存储一些secret配置数据。我只是在开发环境中使用该文件。在生产中,我使用ENV变量。这是我现在正在做的事情:我有一个config/confidental.yml文件,看起来像这样:email:user_name:'my_user'password:'my_passw'我有一个config/environments/development.rb文件(除其他外)有这些行:#Mailerconfigemail_confidential=YAML.load_file("#{Rails.root}/config/confidential.yml")['email']c
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我使用PHP的时间太长了,对它感到厌倦了。我也想学习一门新语言。我一直在使用Ruby并且喜欢它。我必须在Rails和Sinatra之间做出选择,那么您会推荐哪一个?Sinatra真的不能用来构建复杂的应用程序,它只能用于简单的应用程序吗?
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我有一个包含600个模型的Rails应用程序,很快就会增加到800-1000个。我想对Rails应用程序进行分段,以便仅加载某些模型,因此充当单独的应用程序,但所有模型都共享相同的基本模型。是否有执行此操作的标准做法?编辑:我在2.3.8编辑2:问题是许多模型是相似的,但不同之处恰恰足以保证编写一个新类,也就是说,将所有模型都放在一个模型中所需的逻辑将是
我有这个数组对:[{"a"=>"1"},{"b"=>"2"},{"a"=>"3"},{"b"=>"4"},{"a"=>"5"}]我想要一种方法来将具有多个值的公共(public)键合并到:[{"a"=>["1","3","5"]},{"b"=>["2","4"]}] 最佳答案 根据Marc-Andre的建议进行了改进。array=[{"a"=>"1"},{"b"=>"2"},{"a"=>"3"},{"b"=>"4"},{"a"=>"5"}]array.group_by(&:keys).map{|k,v|{k.first=>v.fla
我很确定Ruby有这些(等同于__call、__get和__set),否则find_by将如何在Rails中工作?也许有人可以举一个简单的例子来说明如何定义与find_by相同的方法?谢谢 最佳答案 简而言之你可以映射__调用带有参数的method_missing调用__设置为方法名称以'='结尾的method_missing调用__获取不带任何参数的method_missing调用__调用PHPclassMethodTest{publicfunction__call($name,$arguments){echo"Callingob
Lisp是否适合Web编程/应用程序(交互式),就像ruby和php一样?需要考虑的事情是:易于使用可部署性难度(尤其是对于编程初学者而言)(编辑)在阅读PaulGraham'sessay之后,我特别提到了CommonLisp.将是我的第一门编程语言。在这方面。这样做合适吗?我听说Clojure的宏功能不如CommonLisp的强大,这就是我尝试学习Clojure的原因。它教授编程并且非常强大。 最佳答案 Lisp是一个语系,而不是单一的语言。为了稍微回答您的问题,是的,存在用于各种Lisp方言的Web框架,例如用于Common
项目背景和意义 目的:本课题主要目标是设计并能够实现一个基于微信校园跑腿小程序系统,前台用户使用小程序发布跑腿任何和接跑腿任务,后台管理使用基于PHP+MySql的B/S架构;通过后台管理跑腿的用户、查看跑腿信息和对应订单。意义:手机网络时代,大学生通过手机网购日常用品、外卖外卖、代取快递等已不再是稀奇的事情。此外,不少高校还流行着校园有偿工作,校园跑腿就成了大学生创业服务项目。 因为你在校园里,所以不会有进入的限制。并不是所有的外卖平台都可以随意进入校园,比如小黄和小蓝的双打外卖平台。许多大学禁止送餐进入学校,更不用说送餐进入宿舍了。这一措施使得校园服务市场的竞争相对不