当前位置: 首页 > 知识库问答 >
问题:

MySQL查询慢,按订单按限额分组

袁雅逸
2023-03-14

我目前加入了5个表来选择20个对象显示给用户,不幸的是,如果我使用group byorder by,它会变得非常慢。

SELECT r.name, l.name, o.typ, o.id, persons, children, description, rating, totalratings, minprice, picture FROM angebote as a 
JOIN objekte as o ON a.fid_objekt = o.id 
JOIN regionen as r ON a.fid_region = r.id 
JOIN laender as l ON a.fid_land = l.id 
WHERE l.slug="aegypten" AND a.letztes_angebot >= 1 
GROUP BY a.fid_objekt ORDER BY rating DESC LIMIT 0,20 

查询的解释显示如下:

+------+-------------+-------+--------+----------------------------+------------+---------+---------------------------------------+--------+--------------------------------------------------------+
| id   | select_type | table | type   | possible_keys              | key        | key_len | ref                                   | rows   | Extra                                                  |
+------+-------------+-------+--------+----------------------------+------------+---------+---------------------------------------+--------+--------------------------------------------------------+
|    1 | SIMPLE      | l     | ref    | PRIMARY,slug               | slug       | 767     | const                                 |      1 | Using index condition; Using temporary; Using filesort |
|    1 | SIMPLE      | o     | ALL    | PRIMARY                    | NULL       | NULL    | NULL                                  | 186779 | Using join buffer (flat, BNL join)                     |
|    1 | SIMPLE      | a     | ref    | unique_key,letztes_angebot | unique_key | 8       | ferienhaeuser.o.id,ferienhaeuser.l.id |      1 | Using where                                            |
|    1 | SIMPLE      | r     | eq_ref | PRIMARY                    | PRIMARY    | 4       | ferienhaeuser.a.fid_region            |      1 |                                                        |
+------+-------------+-------+--------+----------------------------+------------+---------+---------------------------------------+--------+--------------------------------------------------------+

所以看起来它没有为objekte表使用键,分析说明它使用2.7s复制到tmp表。

没有使用from Angebotejoin objekte,我尝试使用(SELECT*GROUP BY id),但不幸的是,这没有改善。

我想我错过了一些基本的概念在这里和任何帮助将是感激的。

由于很可能是我弄错了表,下面是对表的描述:

Objekte



+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| objekte | CREATE TABLE `objekte` (
  `id` int(11) NOT NULL,
  `typ` varchar(50) NOT NULL,
  `persons` int(11) NOT NULL,
  `children` int(11) NOT NULL,
  `description` text NOT NULL,
  `rating` float NOT NULL,
  `totalratings` int(11) NOT NULL,
  `minprice` float NOT NULL,
  `picture` varchar(255) NOT NULL,
  `last_offer` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `minprice` (`minprice`),
  KEY `rating` (`rating`),
  KEY `last_offer` (`last_offer`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+---------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+



    +-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| angebote | CREATE TABLE `angebote` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `fid_objekt` int(11) NOT NULL,
  `fid_land` int(11) NOT NULL,
  `fid_region` int(11) NOT NULL,
  `fid_subregion` int(11) NOT NULL,
  `letztes_angebot` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_key` (`fid_objekt`,`fid_land`,`fid_region`,`fid_subregion`),
  KEY `letztes_angebot` (`letztes_angebot`),
  KEY `fid_objekt` (`fid_objekt`),
  KEY `fid_land` (`fid_land`),
  KEY `fid_region` (`fid_region`),
  KEY `fid_subregion` (`fid_subregion`)
) ENGINE=InnoDB AUTO_INCREMENT=2433073 DEFAULT CHARSET=utf8 |
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+


laender,regionen,subregionen(结构相同)


+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| laender | CREATE TABLE `laender` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `iso` varchar(2) NOT NULL,
  `name` varchar(255) NOT NULL,
  `slug` varchar(255) NOT NULL,
  `letztes_angebot` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `iso` (`iso`),
  KEY `slug` (`slug`),
  KEY `letztes_angebot` (`letztes_angebot`)
) ENGINE=InnoDB AUTO_INCREMENT=107 DEFAULT CHARSET=utf8 |
+---------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+


共有1个答案

龚奇逸
2023-03-14

首先,这是一个不规范的群体。因此,当您升级到MySQL5.7时,它将停止工作。

最大的问题来自于在objekte表上没有使用索引。更糟糕的是,您正在对该表的评级字段进行排序,但索引仍未使用。一个可能的解决方案是创建一个复合索引,如下所示:

CREATE INDEX objekte_idx ON objekte(id,rating);
 类似资料:
  • 问题内容: 有没有一种简单的方法可以将GROUP BY结果限制在前2位。以下查询返回所有结果。使用“ LIMIT 2”将整个列表减少到仅前2个条目。 结果如下: 谢谢乔恩 根据要求,我附上了表格结构和一些测试数据的副本。我的目标是创建一个视图,该视图具有每个唯一的rating_name的前2个结果 问题答案: 我认为MySQL中没有简单的方法。一种方法是通过为按rating_name分组的每一行生

  • 问题内容: 我在MySQL中有一张表,该表显示了我每天记录的小时数。我正在尝试建立一个视图,该视图将允许我按块/天范围快速将数据分组。最简单的情况是每月一次,这并不难。我可以将日期选择为“%y-%m”,然后按该列分组。 前任: 如果我按月分组,那很好。但是我的问题是,我需要从每月的13号到下个月的12号进行分组(例如:7月13日至8月12日,8月13日至9月12日,等等)。 有没有一种简单的方法可

  • 这有点奇怪,但是我很难找到如何做到这一点的答案: 我试图创建一个自定义查询,获取WooCommerce订单中包含的所有产品(及其元)。 例如,假设我有这些订单悬而未决: 产品1 产品2 产品3 产品4 产品5 产品6 我的目标是根据这些已订购的产品创建一个列表,该列表由产品的元数据进行订购。大概是这样的: 产品1 产品3 产品4 但同样,这些只是订单中的产品(包括其数量)。 我面临的问题是,数据库

  • 我的问题是空值必须是最后一个order by语句。下面是我的代码截图。我使用javax持久性标准生成器。我的问题很复杂。 如何通过criteria builder以零价格完成订单?

  • 我从sqlite数据库中获取一些数据,在添加order by子句之前,我的查询工作正常 我的查询结构如下 选择*从测试,其中测试像'%test%'COLLATE NOCASE LIMIT 100 OFFSET 0 这运行得很好,我在数据库的前100行获得了包含单词test的所有记录,但是当我以这种方式添加ORDER BY子句时 选择*从TESTI,其中TESTO喜欢'%test%'COLLATE

  • 问题内容: 我正在尝试在postgres中的查询中使用group by。我无法按照我想要的方式对其进行工作,以便根据需要对结果进行分组。 这是对我刚刚回答的递归查询的另一个堆栈问题的扩展。但是现在我需要能够将结果分组到最终查询的root_id列上。这是之前的查询: 这是我想做的,以便将具有相同parent_comment_id的所有记录保存在一起。 可能有许多记录返回了相同的parent_comm