标签: sql-optimization

如何优化查询的执行计划,多个外连接到大表,分组和顺序子句?

我有以下数据库(简化):

CREATE TABLE `tracking` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `manufacture` varchar(100) NOT NULL,
  `date_last_activity` datetime NOT NULL,
  `date_created` datetime NOT NULL,
  `date_updated` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `manufacture` (`manufacture`),
  KEY `manufacture_date_last_activity` (`manufacture`, `date_last_activity`),
  KEY `date_last_activity` (`date_last_activity`),
) ENGINE=InnoDB AUTO_INCREMENT=401353 DEFAULT CHARSET=utf8

CREATE TABLE `tracking_items` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tracking_id` int(11) NOT NULL,
  `tracking_object_id` varchar(100) NOT NULL,
  `tracking_type` int(11) NOT NULL COMMENT 'Its used to specify the type of each item, e.g. car, bike, etc',
  `date_created` …
Run Code Online (Sandbox Code Playgroud)

mysql sql select innodb sql-optimization

6
推荐指数
1
解决办法
331
查看次数

如何在MySQL中有效地选择随机记录?

mysql> EXPLAIN SELECT * FROM urls ORDER BY RAND() LIMIT 1;
+----+-------------+-------+------+---------------+------+---------+------+-------+---------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra                           |
+----+-------------+-------+------+---------------+------+---------+------+-------+---------------------------------+
|  1 | SIMPLE      | urls  | ALL  | NULL          | NULL | NULL    | NULL | 62228 | Using temporary; Using filesort |
+----+-------------+-------+------+---------------+------+---------+------+-------+---------------------------------+
Run Code Online (Sandbox Code Playgroud)

以上不符合效率,我该怎么做呢?

UPDATE

似乎使用答案中提到的解决方案仍无济于事:

mysql> explain SELECT  *
    -> FROM    (
    ->         SELECT  @cnt := COUNT(*) + 1,
    ->                 @lim := 10 …
Run Code Online (Sandbox Code Playgroud)

mysql sql-optimization

5
推荐指数
1
解决办法
563
查看次数

mysql"group by"查询非常慢

我在一个有大约100k记录的表中有这个查询,它运行得很慢(3-4s),当我取出组时它更快(少于0.5s).我很想知道如何解决这个问题:

SELECT msg.id,
       msg.thread_id,
       msg.senderid,
       msg.recipientid, 
       from_user.username AS from_name,
       to_user.username AS to_name
FROM msgtable AS msg
LEFT JOIN usertable AS from_user ON msg.senderid = from_user.id
LEFT JOIN usertabe AS to_user ON msg.recipientid = to_user.id
GROUP BY msg.thread_id
ORDER BY msg.id desc
Run Code Online (Sandbox Code Playgroud)

msgtable上有索引thread_id,id,senderidrecipientid.

解释回报:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  msg ALL NULL    NULL    NULL    NULL    162346  Using temporary; Using filesort
1   SIMPLE  from_user   eq_ref  PRIMARY PRIMARY …
Run Code Online (Sandbox Code Playgroud)

mysql sql sql-optimization

5
推荐指数
1
解决办法
5227
查看次数

如何让MS-Access为我的查询选择不同/正确的执行计划

我有一个相对简单的查询问题和执行计划Access选择它.

查询是这种形式

SELECT somethings
FROM A INNER JOIN (B INNER JOIN (C INNER JOIN D ON ...) ON ...) ON ...
WHERE A.primaryKey= 1 AND D.d = 2;
Run Code Online (Sandbox Code Playgroud)

C和D的行数相对较少.A和B有几千行.

该查询返回2行(不确定这是否相关)真的很慢.它运行17秒.如果我删除AND D.d = 2where子句的一部分,查询现在返回4行并立即运行.

所以我的理解是JET引擎可以立即运行查询而不在Dd上使用过滤器,然后立即执行所述过滤器(仅过滤4行).因此,使用D.d = 2过滤器运行查询不应该太长.

我试图创建一个没有过滤器的子查询,并将其包含在另一个只过滤结果的查询中,但它仍然很慢.我的猜测是JET引擎足够聪明以"扁平化"子查询,因此结果是相同的.

因为我无法按照我的意愿运行查询,所以我使用了JETSHOWPLAN,以便Access输出它的执行计划.这是我发现的:

对于快速查询(没有D.d = 2),查询计划的第一步是A.primaryKey = 1在A表上应用过滤器.这导致超过30000的数据集为1行.然后,连接似乎是使用索引从A到D执行,数据集永远不会超过4行.

慢查询似乎以逆转顺序执行.首先连接D和C然后D.d = 2进行测试.之后,执行从C到A的连接.通过这种方式,需要从D到C,从C到B以及从B到A连接的数据要大得多.当执行所有JOIN并且执行之前A.primaryKey=1,数据集将具有120K行.

有没有办法在Access上强制执行正确的查询计划?

我希望我很清楚.如果我发布查询计划,请告诉我.我没有,因为它们很大.

提前致谢,

熔点

ms-access sql-optimization sql-execution-plan

5
推荐指数
1
解决办法
716
查看次数

如何获取MySql中具有2.5m行的最后一条记录

我想获取MySql表中的最后一条记录,但是该表有250万行。如何有效地获得最后一行?

我正在使用订单和限价单,但查询运行时间约为15秒。我必须将此值减小到几乎为零。

我的SQL查询:

从table1的SELECT ID中,scenedevice_id = X AND module_id = Y ORDER BY ID DESC LIMIT 0,1

编辑:我也尝试了MAX(id)。

编辑:这是我的桌子-

CREATE TABLE IF NOT EXISTS `realtimedevicedata` (
  `id` int(11) NOT NULL auto_increment,
  `scenedevice_id` int(11) NOT NULL,
  `module_id` int(11) NOT NULL,
  `subid` tinyint(4) NOT NULL default '1',
  `value` varchar(30) collate utf8_turkish_ci NOT NULL,
  `timestamp` datetime NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `scenedevice_id` (`scenedevice_id`),
  KEY `module_id` (`module_id`),
  KEY `timestamp` (`timestamp`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_turkish_ci AUTO_INCREMENT=2428598 ;
Run Code Online (Sandbox Code Playgroud)

谢谢。

mysql sql optimization sql-optimization

5
推荐指数
1
解决办法
7741
查看次数

MySQL查询优化:如何优化投票计算?

希望你做得很好.

我需要一点这个数据库的帮助:

在此输入图像描述

这是一个存储投票的数据库.用户选择他们喜欢的音轨,然后投票给他们.他们可以"投票"或"投票"投票.非常简单.但是,当谈到计算统计数据时,它变得毛茸茸.

它是一个键值样式表,存储最常用的统计信息(只是排序缓存):

mysql> SELECT * FROM Meta;
+-------------+-------+
| Key         | Value |
+-------------+-------+
| TRACK_COUNT | 2620  |
| VOTE_COUNT  | 3821  |
| USER_COUNT  | 371   |
+-------------+-------+
Run Code Online (Sandbox Code Playgroud)

投票

投票表持有投票本身.这里唯一有趣的领域是Type,其价值意味着:

  1. 0 - 应用程序投票,用户使用UI投票选择了赛道
  2. 1 - 导入投票(来自外部服务)
  3. 2 - 合并投票.实际上与导入的投票相同,但它实际上已经注意到,该用户已经使用外部服务投票支持此曲目,现在他正在重复使用该应用程序.

跟踪

该轨道保留了自己的总统计数据.喜欢,不喜欢外来服务(LikesRP),不喜欢外部服务(DislikesRP),喜欢/不喜欢调整的数量.

应用

该应用程序需要获得投票:

  1. 在过去7天内,有5个最多投票的曲目
  2. 在过去的7天里,有5首最受欢迎的曲目
  3. 在过去7天内投票最多的5首曲目,其投票均来自外部服务(Vote.Type = 1)
  4. 上个月有100个最多投票的曲目

要获得100个最常用的投票曲目,我使用此查询:

SELECT
    T.Hash,
    T.Title,
    T.Artist,
    COALESCE(X.VotesTotal, 0) + T.LikesAdjust as VotesAdjusted
FROM (
    SELECT
        V.TrackHash,
        SUM(V.Vote) AS VotesTotal …
Run Code Online (Sandbox Code Playgroud)

mysql sql sql-optimization

5
推荐指数
1
解决办法
275
查看次数

为什么我需要在 mysql (InnoDB) 中回滚 SELECT?

SELECT *对 mysql 数据库中的大型 InnoDB 表进行了不明智的操作。

因此,大约 10 分钟后,我意识到了错误,找到了connectionidwith show processlist,并尝试使用 kill 命令终止连接和查询。然后我在同一张表上运行了另一个查询。

show processlist显示原始选择已收到 Killed 标志,但卡在“正在发送数据”状态。后续查询正在等待锁定。这已经持续了几个小时。

现在我明白了,如果我的原始查询以任何方式修改了表,那么我所描述的将等待回滚。

但这是一个select; 回滚 select 甚至意味着什么?

所以我想知道是否有人可以告诉我我在等待什么,以及是否有任何方便的方法来取消select查询。

mysql sql innodb sql-optimization

5
推荐指数
1
解决办法
1228
查看次数

Sql Server:无法有效使用选择性XML索引

我正在探索提高应用程序性能的方法,我只能在有限的程度上影响数据库级别.SQL Server版本是2012 SP2,有问题的表和视图结构是(我不能真正影响这个+注意,xml文档可能总共有几百个元素):

CREATE TABLE Orders(
    id nvarchar(64) NOT NULL,
    xmldoc xml NULL,
    CONSTRAINT PK_Order_id PRIMARY KEY CLUSTERED (id)
);

CREATE VIEW V_Orders as
SELECT 
    a.id, a.xmldoc
    ,a.xmldoc.value('data(/row/c1)[1]', 'nvarchar(max)') "Stuff"
    ,a.xmldoc.value('data(/row/c2)[1]', 'nvarchar(max)') "OrderType"
etc..... many columns
from Orders a;
Run Code Online (Sandbox Code Playgroud)

一个典型的查询(以及下面用于测试的查询):

SELECT id FROM V_Orders WHERE OrderType = '30791'
Run Code Online (Sandbox Code Playgroud)

所有查询都是针对视图执行的,我既不会影响查询,也不会影响表/视图结构.

我认为在表中添加一个选择性XML索引将是我的救星:

CREATE SELECTIVE XML INDEX I_Orders_OrderType ON Orders(xmldoc)
FOR(
    pathOrderType = '/row/c2' as SQL [nvarchar](20)
)
Run Code Online (Sandbox Code Playgroud)

但即使在更新统计数据后,执行计划看起来也很奇怪.无法将图片作为新帐户发布,因此相关详细信息如下:

  • 聚集索引从selectiveXml寻求(成本:总计的2%).预期行数1但预期执行次数1269(表中的行数)
  • - >排名前N的排序(费用:总计的95%)
  • - >计算标量(成本0)

  • 单独分支:聚集索引扫描PK_Order_id(成本:总计的3%).预期行数1269

  • - >使用嵌套循环合并到计算机标量结果(左外连接)
  • - >过滤器
  • - >最终结果(预期行数1269)

实际上,对于我的测试数据,查询甚至不会返回任何结果,但是它是返回一个还是几个没有任何区别.执行时间支持查询,只要可以从执行计划中推断出并且具有数千个读取计数.

所以我的问题是为什么优化器没有正确使用选择性xml索引?或者我有什么不对劲?如何使用选择性xml索引(或者可能是持久列)来优化此特定查询的性能? …

xml sql-server performance sql-optimization

5
推荐指数
1
解决办法
833
查看次数

基于游标的分页中的页码和总结果计数

虽然这听起来像是一个愚蠢的问题,但有时有必要显示页码(以及最后一页)。在基于游标的分页中计算总行数并计算页码(通过提供页面查询以返回特定页面)的最佳方法是什么?所有这些都可以在单个查询中实现吗?

流行的例子:谷歌使用基于光标的分页和行数在谷歌搜索中显示页码。

mysql sql pagination sql-optimization database-optimization

5
推荐指数
1
解决办法
4972
查看次数

PostgreSQL 中名字和姓氏串联搜索的优化

我在 Postgres 中编写了一个 SQL 查询,它可以按名字和姓氏搜索用户。我的问题很简单,它是否可以优化,因为它会被大量使用。

CREATE INDEX users_firstname_special_idx ON users(firstname text_pattern_ops);
CREATE INDEX users_lastname_special_idx ON users(lastname text_pattern_ops);

SELECT id, firstname, lastname FROM users WHERE firstname || ' ' || lastname ILIKE ('%' || 'sen' || '%') LIMIT 25;
Run Code Online (Sandbox Code Playgroud)

如果我运行解释,我会得到以下输出:

Limit  (cost=0.00..1.05 rows=1 width=68)
  ->  Seq Scan on users  (cost=0.00..1.05 rows=1 width=68)
        Filter: (((firstname || ' '::text) || lastname) ~~* '%sen%'::text)
Run Code Online (Sandbox Code Playgroud)

据我了解,我应该尝试让 postgrep 跳过“Filter:”-东西。那是对的吗?

希望大家有什么建议。

干杯。

postgresql sql-optimization

4
推荐指数
1
解决办法
4740
查看次数