在 MySQL 中为 perfromant 连接的两个属性键入唯一表的最佳方法?

Posted

技术标签:

【中文标题】在 MySQL 中为 perfromant 连接的两个属性键入唯一表的最佳方法?【英文标题】:Best way to key a table that is unique on two attributes for perfromant joins in MySQL? 【发布时间】:2016-05-14 20:56:28 【问题描述】:

我有一个成本表,用于存储某项特定日期的成本。 表格如下

===============================
id   item_id   cost_date   cost
===============================

其中 id 是主键,item_id 是 items 表的外键,cost_date 是项目可用的日期,cost 是项目的成本。我也有一个订单表

==============
id  order_date   
==============

其中 id 是主键,date 是订购日期。如果一个项目是在特定日期订购的,它应该有成本条目,其中 cost_date 与它所属的订单的 order_date 匹配。 最后我有一个 orders_items 表

==============================
id   order_id  item_id   price
==============================

其中 id 是主键,order_id 是订单的外键,item_id 是商品的外键,price 是该特定订单中商品的价格。

我经常想同时查看价格和成本,这会导致这组讨厌的连接。

FROM orders_items
LEFT JOIN items ON orders_items.item_id = items.id
LEFT JOIN orders ON orders_items.order_id = orders.id
LEFT JOIN costs ON costs.date = orders.date AND costs.item_id = items.id

我必须为成本执行双重联接这一事实确实减慢了我的查询速度。我想知道是否有一种方法可以更改允许一组从长远来看性能更高的连接的键? 是否有一个好地方可以为costs.id 创建一个外键,它对于cost 中的每一行都是唯一的,并且可以消除对双重连接的需要?

【问题讨论】:

请显示您的表定义,包括索引。 costs 需要 INDEX(date, item_id)(以任意顺序)。或者,或许已经是PK了?性能应该不会太差。 【参考方案1】:

连接本身并没有减慢您的速度。您的表格已适当规范化。

从您使用表的方式来看,pair (item_id , cost_date) 在 Costs 中是 UNIQUE NOT NULL。告诉 DBMS。

索引您的外键列集及其引用的列,因为您希望快速连接它们:项目 (id)、成本 (id) & (item_id 、 cost_date)(在 mysql 中用于索引 (item_id) & (cost_date)) , Orders (order_date) 和 Orders_items (order_id) & (item_id)。请注意,您实际上并不需要 Costs id 和 Orders_items id,因为这些表/关系具有自然键。 MySQL 自动索引 PRIMARY KEY。

外键声明有很大的不同,因为 DBMS 知道当它找到匹配项时没有其他匹配项。索引有很大的不同,因为它们要么避免扫描(散列),要么缩短它们(排序),并且可以避免访问二级存储。

非规范化引入了要管理的冗余,包括额外的代码和更新计算,并且可以大大增加表的大小,增加行的大小,迫使数据从内存访问到二级存储。只做最直接的设计。之后确定最有效的地方,只有在测量和确认后才进行优化和反规范化。

MySQL 5.7 Reference Manual 8.3 Optimization and Indexes

PS 这里最直接的查询是使用 INNER JOIN。

【讨论】:

以上是关于在 MySQL 中为 perfromant 连接的两个属性键入唯一表的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

左连接在 MySQL 中为空

在树莓派中为 python 3 安装 mysql 连接器

Perl Apache 脚本按预期从 browser-perfroms 运行关闭正在运行的 perl 实例,但是当尝试启动新的 perl 实例时它啥也不做

在休眠中为同一实体的 MySQL 和 SQL 服务器配置差异表名称

如何在 Spring Boot / Spring Data 中为 Amazon RDS Mysql 启用 SSL?

mysql 自连接查询