gpt4 book ai didi

php - 在 PHP 中加入分解

转载 作者:可可西里 更新时间:2023-11-01 07:35:50 25 4
gpt4 key购买 nike

我看到一篇关于 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com