【问题标题】:INNER JOIN ON multiple attributes not workingINNER JOIN ON 多个属性不起作用
【发布时间】:2018-07-03 13:40:05
【问题描述】:

我需要用另一个表中的值更新一列……但这需要永远或中止。可以在多个交易所(麦克风)中列出特定的证券(isin)......所以我认为我需要在 INNER JOIN 中有两个条件...... ON(??)。我的以下尝试正确吗?我在表中有大约 170,000 条记录,其中包含 40,000 个唯一的 isins。

第一次尝试:

SQL:
SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
    ON t1.isin = t2.isin AND t1.mic = t2.mic
SET t1.prev_close = t2.close;

第二次尝试:

SQL:
SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
    ON (t1.isin = t2.isin AND t1.mic = t2.mic)
SET t1.prev_close = t2.close;

目前对两个表的索引进行编辑:

Indexes (securities_live):
Primary|Unique=Yes|Packed=no|Column=id|Cardinality=166776|Collation=A

Indexes (securities_prev):
Primary|Unique=Yes|Packed=no|Column=id|Cardinality=166776|Collation=A

在这两个表中,我在列“id”上都有一个主键。所以例如在表Securities_live“创建新索引”中,一个用于列isin,另一个用于列mic?索引名称和索引类型(Primary、Index、Unique、Fulltext)呢?尺寸?

【问题讨论】:

  • 唯一能想到的可能有帮助的可能是在一个或两个表上添加索引以加快更新中的连接。
  • 如果你已经有了合适的索引,但仍然很慢,你还应该确保两个表之间的 isin 和 mic 的数据类型相同。看看你的execution plan,看看你是否能发现任何问题(例如表扫描,或者优化器选择了错误的索引)

标签: mysql sql join inner-join


【解决方案1】:

对于这个查询:

UPDATE securities_live t1 INNER JOIN
       securities_prev t2
       ON t1.isin = t2.isin AND t1.mic = t2.mic
    SET t1.prev_close = t2.close;

我建议在securities_prev(isin, mic, close) 上建立索引。

但是,我怀疑您正在更新所有或几乎所有记录。如果是这种情况,通常截断表并使用insert 重新填充它会更快。 Update 最适合用于更新相对较少的行数。

【讨论】:

  • 那么为表Securities_live创建3个新索引('创建一个新索引')为isin、mic和close?索引名称和索引类型(Primary、Index、Unique、Fulltext)呢?尺寸?
  • 建议只创建一个索引,但在多个列上。
  • @Kobi ...所以“索引名称”无关紧要...但是索引类型呢?主要、索引、唯一、全文? ...并将其映射到这 3 列?
  • 一个简单的索引 => CREATE INDEX idx_foobar ON securities_prev(isin, mic, close)
  • ...非常感谢。我已经对其进行了测试,现在大约需要 11 秒……所以我已经很满意了……谢谢!
【解决方案2】:

正如评论者所指出的,既然您已经设置了索引,我建议您尝试零碎地进行这些操作。一次做 5k 次,直到完成。试试10k。显然你不能做 170k 或 40k。我曾多次遇到数据库有数百万行的情况,而我一次只能处理 100k 或更少的行。这是因为硬件的限制。

例如,

UPDATE top(1000) securities_live t1
INNER JOIN securities_prev t2
    ON t1.isin = t2.isin AND t1.mic = t2.mic
SET t1.prev_close = t2.close;

您可能希望使用 Order By 以便了解哪些记录是什么,并且您需要跟踪已更新的内容。

看这里,

how can I Update top 100 records in sql server

抱歉,我刚刚看到您使用的是 MySQL,

MySQL - UPDATE query with LIMIT

【讨论】:

  • 谢谢,我试试看。
  • 查看我的编辑。您不想每次都更新相同的 1000 行。
  • 是的...第一个示例导致错误。如果我使用 LIMIT 会自动执行另一个块吗?
  • @PhilippM 我不认识你。此时您正在手动执行操作,因为您的硬件、网络或设计无法承受。
  • ... 设置上面建议的索引(我没有)已经有帮助...索引需要 11 秒,这对我来说很好。但也感谢您的帮助!
【解决方案3】:

试试这个:

SET SESSION SQL_BIG_SELECTS = 1;
UPDATE securities_live t1
INNER JOIN securities_prev t2
    ON (t1.isin = t2.isin AND t1.mic = t2.mic)
SET t1.prev_close = t2.close;

【讨论】:

  • 您的查询与 OP '第二次尝试'有什么区别?
  • 不同之处在于我将条件绑定在括号内,因此在编译器部分中查询将易于理解
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
相关资源
最近更新 更多