【问题标题】:MySQL Database Table optimization for FASTER Querying & PerformanceMySQL 数据库表优化以实现更快的查询和性能
【发布时间】:2019-06-04 13:40:41
【问题描述】:

我的 MySQL 数据库中有 2 个表。 让我们打电话给第一个main,第二个final

TABLE `main` has the structure         |    TABLE `final` has the structure
                                       |
`id` --> PRIMARY KEY (Auto Increment)  |    `id` --> PRIMARY KEY (Auto Increment)
                                       |    `id_main` -->  ?? (Need help here)
                                       |
id | name    | info                    |     id | id_main | name    | info(changed)
---------------------                  |     ---------------------------------------
1  | Peter   | 5,9                     |     1 |    2     | Butters  | 0.3,34
2  | Butters | 3,3                     |     2 |    4     | Stewie   | 1.2,4.4
3  | Stan    | 2,96                    |     3 |    1     | Peter    | 5.7,0.9
4  | Stewie  | 1,84                    |     4 |    3     | Stan     | 4.8,0.74

分析main 中的数据后,将结果放入final。 如您所见,final 有一个额外的列 (id_main),它指向 main.id

实际上这两个表各有 1 亿多行,我的问题是在执行 SQL 查询时出现的。

final 尤其是 (id & id_main) 应该如何配置,以便从main 查询到final 最快。

我可以取消final.id(主键,自动增量)并保留 final.id_main(作为唯一索引?)

我应该保留id 作为主键 (AI) 和 final.id_main 作为唯一索引吗?

我会打这样的电话:

int id_From_Main= 10000;
SELECT `id_main` FROM `final` WHERE `id`='"+id_From_Main+"'

【问题讨论】:

  • 查询SELECT id_main FROM final WHERE id='"+id_From_Main+"'的目的是什么?您正在尝试通过来自 main 的 ID 从 main 中选择 ID 的值。
  • 请提供您需要帮助的SHOW CREATE TABLESELECT
  • 或者您的问题是关于如何有效地将INSERT 100M 行转换为final?还是你使用UPDATE

标签: mysql database performance primary-key database-indexes


【解决方案1】:

如果这些表之间存在 1:1 的关系,我看不出它们需要两个单独的自动递增主键的任何理由。

我将删除final.id 列,并将final.id_main 作为非自动递增的主键和main.id 列的外键。

一般来说,您也可以有一个根本没有主键的表。这取决于您是否希望能够选择特定的单个行。

我不明白您的查询SELECT id_main FROM final WHERE id = '"+id_From_Main+"' — 您正在尝试通过来自 main 的 ID 从 main 中选择 ID 的值。目的是什么,你为什么要试图获得你已经拥有的价值?

无论如何,您没有提供足够的信息来给您一个合格的答案。您必须根据您将要执行的查询来优化您的数据结构。

确保您在 WHERE 子句中使用的列上有索引。如果您通过final.id_main 进行选择,请在该列上有一个索引。如果您通过final.id_mainfinal.name 选择,则在两列上都有一个复合索引,等等。

您真的需要在两个表中都有name 列吗?这是一个糟糕的数据库设计,除非它是一些性能优化(以避免连接)。

所以,你应该:

  1. 收集您当前正在使用的所有查询,并根据它们设置适当的索引
  2. 删除所有不必要的列(例如final.idfinal.name
  3. 在您的查询中使用EXPLAIN 来获取执行信息(您也可以使用Explain analyzer 来帮助您解释结果)
  4. 你可以试试query profiling

【讨论】:

  • 我在final.id_main as a non-auto-incremented primary key 上完全同意你的看法,但在foreign key to the main.id column 部分不同意,我认为这样做没有任何性能优势,外键的主要目的不是帮助数据库管理员桌子之间的机动?哈哈对不起,我应该详细说明int id_From_Main= 10000; SELECT id_main FROM final WHERE id='"+id_From_Main+"'是java代码。
  • @InternetOfThings - FOREIGN KEYs 做三件事:(1) 完整性检查(在本问答中没有问题),以及 (2) 如果还没有 INDEX,则提供,以及( 3) 告诉 humans 这些表是如何关联的。因为PRIMARY KEY UNIQUE INDEX,你已经满足(2)。 (1) 和 (3) 并不重要。
  • @InternetOfThings 不管是什么语言,它在逻辑上都没有意义。您正在尝试选择final.id_main 的值,其中final.id == id_main。只需删除final.id,这在您的情况下似乎没用。
【解决方案2】:

在mysql中,你必须将id定义为PK,因为它是auto_increment。将 id_main 定义为 UNIQUE。

【讨论】:

  • 主键不必自增,表中也不需要自增列。
  • 在mysql中,如果一个列是自增的,它必须在PK中。但是是否需要自增列id不在讨论范围内。
  • 不,这正是 OP 所要求的——如果他应该保留 final.id 自动递增主键或删除它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多