Sql 如何加速mariadb连接表

Sql 如何加速mariadb连接表,sql,indexing,mariadb,Sql,Indexing,Mariadb,我有两个表,我从中加入了某些列。它们在一个VARCHAR列上联接(在两个表中都索引)。表A有超过800000条记录,表B有20000条记录。 表A有一个auto_inc主键。表B没有主键,只有提到的VARCHAR列上的索引 查询耗时约48秒,速度太慢。我能做些什么来提高速度?在表B中创建主键自动增量是否有帮助?即使这不是发生联接的列 开始使用SQL。两个表都是InnoDB,我使用Mariadb 查询: select distinct `pr`.`ProductIdentifier` A

我有两个表,我从中加入了某些列。它们在一个VARCHAR列上联接(在两个表中都索引)。表A有超过800000条记录,表B有20000条记录。 表A有一个auto_inc主键。表B没有主键,只有提到的VARCHAR列上的索引

查询耗时约48秒,速度太慢。我能做些什么来提高速度?在表B中创建主键自动增量是否有帮助?即使这不是发生联接的列

开始使用SQL。两个表都是InnoDB,我使用Mariadb

查询:

select distinct 
    `pr`.`ProductIdentifier` AS `ProductIdentifier`,
    `pr`.`Datum` AS `Datum`,
    `pr`.`Retailer` AS `Retailer`,
    `pr`.`Prijs` AS `Prijs`,
    `pm`.`Merk` AS `Merk`,
    `pm`.`Product` AS `Product`,
    `pm`.`Formaat` AS `Formaat` 
from 
   (`prices`.`prices_table` `pr` 
    join `prices`.`product_match_table` `pm` 
        on(`pr`.`ProductIdentifier` = `pm`.`ProductIdentifier`))
解释选择:


这个答案是基于我对索引的一般知识;MariaDB可能有一些我不知道的更专业的选择

然而,索引从两个方面大大加快了查询速度

  • 只需要拥有所需的列,这意味着需要读取和处理的数据更少
  • 通过以适当的方式进行排序来帮助处理
首先,您通常需要一个

第二,这包括

  • 排序方式与查询中要加入的表相同(例如,在相同字段上编制索引)
  • 排序,以便WHERE子句和其他类型的筛选可以直接使用排序转到索引/表中的适当位置
在实践中,性能上的最佳改进通常是最后一个,但是代码中没有WHERE子句。如果(通常情况下)用户过滤结果(例如,仅在ProductName=‘手提包’的位置显示结果),则您可能需要调整这些结果的索引(稍后将详细介绍)

覆盖上述查询的索引

我认为使用当前的查询(没有过滤等),最快的速度是使用两个索引

CREATE INDEX `IX_prices_ProductIdentifier` ON `prices`.`prices_table` 
    (`ProductIdentifier`,
    `Datum`,
    `Retailer`,
    `Prijs`);
CREATE INDEX `IX_productmatch_ProductIdentifier` ON `prices`.`product_match_table`
    (`ProductIdentifier`,
    `Merk`,
    `Product`,
    `Formaat`); 
这些提供了所示查询的覆盖索引,并且它们的排序相同(按productIdentifier),以使联接更容易

搜索/筛选(初始示例中未指定)

但是,如果人们通常首先按特定字段进行搜索,则有必要对相关表中的字段重新排序(因此搜索的字段是第一个),或者使用多个索引,将搜索字段放在前面

例如,人们可以在
pr
Retailer
pm
Merk
pm
产品中搜索特定值。因此,您可以添加这些附加索引

CREATE INDEX `IX_prices_Retailer` ON `prices`.`prices_table` 
    (`Retailer`,
    `ProductIdentifier`,
    `Datum`,
    `Prijs`);
CREATE INDEX `IX_productmatch_Merk` ON `prices`.`product_match_table`
    (`Merk`,
    `ProductIdentifier`, 
    `Product`,
    `Formaat`); 
CREATE INDEX `IX_productmatch_Product` ON `prices`.`product_match_table`
    (`Product`,
    `ProductIdentifier`, 
    `Merk`,
    `Formaat`); 
请注意,上面提到的字段顺序很重要。数据(索引)按第一个字段、第二个字段、第三个字段等进行排序。要有效使用索引,筛选/WHERE子句需要至少包括第一个字段(如果不是更多的话)

这些索引(用于筛选的索引)的另一种替代方法是使用上述原始两个索引,但随后将一个单独的索引放在他们可以搜索的每个字段上,例如,如果用户可以筛选零售商、merk和产品,则创建

  • pr
    零售商上的一个索引
  • 一个在
    pm
    Merk
    上,以及
  • 一个在
    pm
    Product
注意事项

添加索引会使数据插入到相关表中(通常是删除/更新),这比没有索引时要慢。原因是它不仅需要更新表中的数据,还需要更新索引


通常这不是什么大问题,除非您经常从表中添加和删除大量数据。但在添加索引后,值得检查您的“产品维护”界面(例如,添加产品、更新价格等),以确认它们仍然运行良好。

至少,您需要为要加速的查询显示SQL。请提供
show CREATE TABLE
EXPLAIN SELECT…
查询是什么?我刚刚在原始帖子中添加了它。感谢您花时间回复。我尝试了你的建议,包括索引。它节省了大约10秒,但仍然需要38秒,这对我来说仍然很长。我认为大部分时间都花在匹配栏上,而不是阅读匹配栏后面的栏。。在价格表和产品匹配表中分别有近900.000条记录和14.000条记录(每天增长数千条)。有没有办法改进查询的这一部分?匹配列是长度为125的VARCHAR。我在某个地方读到过,哈希索引可能会有所帮助?当用户使用此报表时,他们会返回多少行?他们每次运行时都会得到900000行吗?还是按特定列过滤?如果是,它们会过滤哪些列?报告不会直接使用。该视图由Google data studio读取(它已经在不同的报告中对“merk”进行了筛选)。如果是这样,我建议在“merk”上添加一个索引。如果这有很大帮助,在上面的答案中考虑名为<代码> ixPuffTrMatthChy-Melk < /Cord>的索引(仅替换Melk上的索引)。但是这不利于视图正确吗?问题不是作为最终用户在Google data studio中进行过滤。DataStudio已经有了一个经过筛选的表,这可以正常工作。我只是认为我可以使视图更好地用于将来的扩展(因为数据库将高速增长)。