【问题标题】:How can optimize this VIEW Statement?如何优化这个 VIEW 语句?
【发布时间】:2011-07-28 13:32:18
【问题描述】:

我有两个表 table1 和 table2。 Table1 由解析器生成,每隔几天自动更新一次。表 2 是表 1 的用户编辑版本。如果 table2 中存在记录,则应覆盖视图中 table1 中的记录。

table2 中的任何编辑版本都分别​​在 OldColumn2 和 OldColumn3 中为 Column2 和 Column3 保留 table1 中的原始内容。当用户删除一条记录时,删除的列的值为1,如果用户想再次添加记录,它的值为0 以显示在视图中。如果从未被删除,默认值为NULL

如果在table2中插入了一条新记录,OldColumn2和OldColumn3的值为new字符串,以区分该记录在table1中不存在。

这是我的桌子的设计。

Table1
+------+------+------+-------------+
| Col1 | Col2 | Col3 | OtherColumns|
+------+------+------+-------------+
|   a1 |   b1 |   c1 |    Data     |
+------+------+------+-------------+
|   a2 |   b2 |   c2 |    Data     |
+------+------+------+-------------+
|   a3 |   b3 |   c3 |    Data     |
+------+------+------+-------------+
|   a4 |   b4 |   c4 |    Data     |
+------+------+------+-------------+


Table2
+------+------+------+-------------+----------+----------+---------+
| Col1 | Col2 | Col3 | OtherColumns| OldCol2  |  OldCol3 | Deleted |
+------+------+------+-------------+----------+----------+---------+
|  a1  |   e1 |  f1  |   Data      |    b1    |     c1   |   NULL  |
+------+------+------+-------------+----------+----------+---------+
|  a2  |   k2 |  m2  |   Data      |    b2    |     c2   |   0     |
+------+------+------+-------------+----------+----------+---------+
|  a3  |   k3 |  m3  |   Data      |    b3    |     c3   |   1     |
+------+------+------+-------------+----------+----------+---------+
|  z1  |   kk |  jj  |   Data      |   new    |   new    |   1     |
+------+------+------+-------------+----------+----------+---------+
|  z2  |   kj |  uu  |   Data      |   new    |   new    |   0     |
+------+------+------+-------------+----------+----------+---------+

    View
+------+------+------+-------------+----------+----------+---------+
| Col1 | Col2 | Col3 | OtherColumns| OldCol2  |  OldCol3 | Deleted |
+------+------+------+-------------+----------+----------+---------+
|  a1  |   e1 |  f1  |   Data      |    b1    |     c1   |   NULL  |
+------+------+------+-------------+----------+----------+---------+
|  a2  |   k2 |  m2  |   Data      |    b2    |     c2   |   0     |//Deleted then added
+------+------+------+-------------+----------+----------+---------+
|  a4  |   k4 |  j4  |   Data      |    NULL  |     NULL |   0     |
+------+------+------+-------------+----------+----------+---------+
|  z2  |   kj |  uu  |   Data      |   new    |   new    |   0     |
+------+------+------+-------------+----------+----------+---------+

这是我的观点声明。

CREATE VIEW NEWVIEW
AS
SELECT t2.* FROM table1 t1
LEFT JOIN table2 t2
ON t1.column1 = t2.column1 AND t1.column2 = t2.oldColumn2 AND t1.column3 = t2.oldColumn3
WHERE t2.column1 IS NOT NULL AND t2.Deleted = 0

UNION

SELECT t1.*, null, null, null FROM table1 t1
LEFT JOIN table2 t2
ON t1.column1 = t2.column1 AND t1.column2 = t2.oldColumn2 AND t1.column3 = t2.oldColumn3
WHERE t2.column1 IS NULL

UNION

SELECT * FROM table2 WHERE oldColumn2 = 'new' AND oldColumn3 = 'new' AND Deleted = 0

现在视图有点慢。如何优化此视图?

【问题讨论】:

  • 这个过程尖叫改变了设计。为什么不直接将新数据从 table1 添加到表 2?
  • Table1 由解析器生成。他们设计解析器的方式是从 table1 中删除所有内容并再次重建它(我继承了它)。因此,任何用户生成的内容都必须存储在另一个表中。如果用户编辑 table1 中的内容,则将其存储在 table2 中。希望说明清楚。
  • 你如何区分a1行没有被删除但是a2已经被删除然后又被添加到你的视图中?还是您的 Table2 中有错误?你关心订单吗?
  • @jswolf19 我使用在两个表中都不会更改的复合键来区分它。复合键位于OtherColumns 中。有超过 25 列,我不想全部写出来,因为它不是必需的。顺序并不重要。如果deleted=1 则不会显示在视图中。但如果是0null,则会显示。起初删除IS NULL,如果他们删除它,它是1,如果他们添加记录而不是添加新记录,我查询数据库并将值更改为0,这样它就不会创建重复并添加在视图中。

标签: mysql sql view query-optimization


【解决方案1】:

尝试用这个更改视图中的前两个 SELECT 语句 -

SELECT
  t1.column1,
  t1.column2,
  t1.column3,
  IF(t2.column1 IS NULL, t1.OtherColumns, t2.OtherColumns) OtherColumns,
  IF(t2.column1 IS NULL, NULL, t2.OldCol2) OldCol2,
  IF(t2.column1 IS NULL, NULL, t2.OldCol3) OldCol3,
  IF(t2.column1 IS NULL, NULL, t2.Deleted) Deleted
FROM
  table1 t1
LEFT JOIN table2 t2
  ON t1.column1 = t2.column1 AND t1.column2 = t2.oldColumn2 AND t1.column3 = t2.oldColumn3
WHERE 
  t2.column1 IS NULL OR t2.column1 IS NOT NULL AND t2.Deleted = 0

请注意,视图可能性能不佳。

【讨论】:

  • 如果您使用union all,您可能还会得到轻微的提升,因为您不应该在两个/三个查询之间有任何重叠。
  • 这并没有真正的帮助,只有一两秒的区别
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
相关资源
最近更新 更多