优化SQL查询 [英] Optimising SQL Queries

查看:112
本文介绍了优化SQL查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在开发一个内容管理系统,我想听听您对以下内容的想法:

I'm developing a content management system at the moment, and I wanted to hear your thoughts on the following:

我有一个表, page 。让我们假设它看起来像这样

I have one table, page. Let's assume it looks like this

ID | Title | Content
1  | Test  | This is a test

除此之外,我有一个 page_option 表(所以我可以存储与页面相关的选项,但我不想有一个有限的选项列表 - 如果需要,模块可以添加自己的选项到页面)。

As well as this, I have a page_option table (so I can store options relating to the page, but I don't want to have a finite list of options - modules could add their own options to a page if required.)

page_option 表可能如下所示:

page_id | option_key  | option_value
1       | background  | red
1       | module1_key | chicken

现在要检索页面对象,我使用Active Record类编码为此问题):

Now to retrieve a page object, I do the following using the Active Record class (this was pseudo coded for this question):

function get_by_id($page_id) {

 $this->db->where('id', $page_id);
 $page_object = $this->db->get('page');

 if($page_object->num_rows() > 0) {

   $page = $page_object->row();
   $this->db->where('page_id', $page_id);
   $options_object = $this->db->get('option');

   if($options_object->num_rows() > 0) {
     $page->options = $options_object->result();
   }

   return $page;

 }

 return $page_object->row();

}

我想知道的是有办法这在一个查询中,以便选项键成为我的选择中的虚拟列,所以我会得到:

What I want to know, is there a way to do this in one query, so that the option keys become virtual columns in my select, so I'd get:

ID | Title | Content        | background | module1_key
1  | Test  | This is a test | red        | chicken

在我的结果中,而不是对每一行执行单独的查询。如果有10,000?

In my results, rather than doing a seperate query for every row. What if there were 10,000? Etc.

提前非常感谢!

推荐答案

使用EAV (实体 - 属性值)模型您将永远不得不应付这些类型的问题。由于查询的复杂性,它们也不是高效的(在大多数情况下需要旋转)。

Using the EAV (Entity-Attribute-Value) model you will always have to cope with these kind of issues. They're also not ver efficient due to the complexity of the queries (pivoting is required in most of them).

SELECT page_id,
  MAX(CASE WHEN option_key = 'background' THEN option_value END) background,
  MAX(CASE WHEN option_key = 'module1_key' THEN option_value END) module1_key,
  MAX(CASE WHEN option_key = 'module2_key' THEN option_value END) module2_key
FROM page_option
GROUP BY page_id

例如,给定此表:

| PAGE_ID |  OPTION_KEY | OPTION_VALUE |
|---------|-------------|--------------|
|       1 |  background |          red |
|       1 | module1_key |      chicken |
|       2 | module1_key |         duck |
|       3 | module1_key |          cow |
|       4 |  background |         blue |
|       4 | module2_key |        alien |
|       4 | module1_key |      chicken |

您将输出以下内容:

| PAGE_ID | BACKGROUND | MODULE1_KEY | MODULE2_KEY |
|---------|------------|-------------|-------------|
|       1 |        red |     chicken |      (null) |
|       2 |     (null) |        duck |      (null) |
|       3 |     (null) |         cow |      (null) |
|       4 |       blue |     chicken |       alien |

Fiddle 此处

然后只需加入它:)我省略了这部分,以集中查询在分组本身。

Then just join with the page table and that's it :) I've omitted that part in order to focus the query in the grouping itself.

这篇关于优化SQL查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆