标签: optimization

如何优化在 SQL Server 中搜索子字符串的列?

我有一个非常基本的表:

CREATE TABLE [obj_local] (
    [obj_id]     INT             NOT NULL,
    [value]      NVARCHAR (1000) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)

这个表存储了很多数据,我需要在value列中搜索一个字符序列:

SELECT [obj_id] FROM [obj_local] WHERE [value] LIKE '%{substring}%'
Run Code Online (Sandbox Code Playgroud)

这是非常缓慢的。我的理解是,由于两边的通配符,索引对我没有帮助,全文索引也对我没有帮助,因为我不是在搜索标记(单词)。

我可以做些什么来优化此搜索?

sql-server-2008 sql-server optimization query-performance

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

为什么 WHERE 子句没有在视图查询中下推?

使用 Postgres 9.4,我经常执行以下查询:

SELECT DISTINCT ON(recipient) * FROM messages
LEFT JOIN identities ON messages.recipient = identities.name
WHERE timestamp BETWEEN timeA AND timeB
ORDER BY recipient, timestamp DESC;
Run Code Online (Sandbox Code Playgroud)

所以我决定创建一个视图:

CREATE VIEW myView AS SELECT DISTINCT ON(recipient) * FROM messages
LEFT JOIN identities ON messages.recipient = identities.name
ORDER BY recipient, timestamp DESC;
Run Code Online (Sandbox Code Playgroud)

我刚刚意识到,如果我查询我的观点,就像SELECT * FROM myView WHERE timestamp BETWEEN timeA AND timeB我的表现要差很多一样。

这样EXPLAIN ANALYZE两个问题,我发现了原因是,在第二种情况下,数据库带来了所有记录,请问左连接,然后应用WHERE条款。换句话说,WHERE子句不会被下推到视图的查询中。我还尝试ORDER BY从视图中删除,但数据库仍然LEFT JOIN对完整数据而不是过滤集执行。

这种行为的原因是什么?有没有办法在使用视图时获得可比较的性能?

postgresql performance optimization view query-performance

4
推荐指数
2
解决办法
2898
查看次数

为什么添加二级索引没有提高选择性能?

我在 MySQL 中有一个名为 的表,messages如下所示:

id (primary key)   | description    |  created_at(timestamp) 
Run Code Online (Sandbox Code Playgroud)

该表应该保存我的应用程序用户之间的聊天消息。因此,对它的写操作次数会很高。

该应用程序有一个 API,可返回两个时间戳之间的所有消息。这个查询也很常见,但少于写操作的次数。

我用 100 个并发连接和该表中的大约 15000 行运行 mysqlslap,总时间约为 8.6 秒。

然后我在 上添加了一个二级索引created_at,希望在两次搜索之间在更短的时间内获得结果,但是对于相同的输入,我增加了 0.3 秒。

为什么我没有看到显着的性能提升?

编辑:

这是我的桌子的样子:

DROP TABLE IF EXISTS `mssg`;

CREATE TABLE `mssg` (
  `id` INTEGER NULL AUTO_INCREMENT DEFAULT NULL,
  `body` MEDIUMTEXT NULL DEFAULT NULL,
  `length` VARCHAR NULL DEFAULT NULL,
  `created_at` TIMESTAMP NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
);
Run Code Online (Sandbox Code Playgroud)

这就是我添加索引的方式:

ALTER TABLE testalter_tbl ADD INDEX (created_at);
Run Code Online (Sandbox Code Playgroud)

通常,select 语句会返回大约 150 到 350 条消息

mysql index optimization

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

选择与左连接中的子查询

通常我必须在获取其他非相关行的查询中返回某些行的计数。

例如一个表用户一个表评论和一个表图片

User:
id
nickname

Review:
id
to_user_id
from_user_id
rating

Picture:
id:
user_id
url
Run Code Online (Sandbox Code Playgroud)

假设我想在一个查询中检索“给定”userId 的所有图片 url 的昵称以及评论该用户的人数。

我认为在执行此查询时的第一种也是简单的方法是:

SELECT
  u.nickname
  (SELECT count(*) FROM review WHERE to_user_id = u.id) as reviewCount,
  p.url
FROM user
LEFT JOIN picture ON p.user_id = u.id
WHERE 
  u.id = 1
Run Code Online (Sandbox Code Playgroud)

这样做的另一种方法是没有那个子选择并通过在正确的 user_id 上加入评论表

SELECT 
 u.nickname,
 r.reviewCount,
 p.url
FROM user u 
LEFT JOIN (
    SELECT to_user_id, count(*) reviewCount FROM review GROUP BY to_user_id
 ) r ON r.to_user_id = u.id
LEFT JOIN picture ON p.user_id …
Run Code Online (Sandbox Code Playgroud)

mysql performance optimization mysql-5.7 query-performance

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

如何避免整数列的隐式转换

  SELECT [BusinessEntityID],[NationalIDNumber],[LoginID],[OrganizationNode]
  FROM [AdventureWorks2014].[HumanResources].[Employee]
  where BusinessEntityID = 5
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

在实际执行计划中执行查询后,我得到了 SQL Server 调用的 convert_implicit() 函数。

  SELECT [BusinessEntityID],[NationalIDNumber],[LoginID],[OrganizationNode]
  FROM [AdventureWorks2014].[HumanResources].[Employee]
  where BusinessEntityID = convert(int,5)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

显然,当我将标量值显式转换为整数类型时,不会调用 convert_implicit() 函数。有什么方法可以避免在不使用显式转换的情况下对标量 int 值进行隐式转换。另外我想知道隐式转换、显式转换和根本没有转换之间的性能差异。

sql-server optimization execution-plan type-conversion

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

加载大量测试数据的快速方法

我试图用大量虚拟数据填充表,以便我可以进行优化等。

我有以下几点:

WHILE @RowCount < 3000000
BEGIN

    SELECT @Random = ROUND(@Upper * RAND(), 0)

    INSERT INTO [dbo].[Test]
               ([Id]
               ,[OtherKey]
               ,[Description])
         VALUES
               (@RowCount
               ,@Random
               ,CAST(@Random AS VARCHAR(max)))

    SET @RowCount = @RowCount + 1
END
Run Code Online (Sandbox Code Playgroud)

然而,这似乎很慢。

有没有更好的方法来自动将半随机行加载到数据库表中?

新脚本

这个似乎很快:

USE [Test]
GO

/****** Object:  Table [dbo].[Test]    Script Date: 17/10/2016 21:22:39 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

USE [Test]
GO

CREATE TABLE [dbo].[Test](
    [Id] [int] NOT NULL,
    [OtherKey] [int] NOT NULL,
    [Description] [varchar](max) NOT NULL,
    [Time] [datetime] NOT NULL
) …
Run Code Online (Sandbox Code Playgroud)

performance sql-server optimization bulk-insert

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

在两个 bigint 列之间搜索的查询的最佳索引策略

我在 MS-SQL 中有下表:

CREATE TABLE [dbo].[dbip_locations](
    [ip_from] [bigint] NOT NULL,
    [ip_to] [bigint] NOT NULL,
    [country_code] [nvarchar](64) NOT NULL,
    [region_name] [nvarchar](128) NOT NULL,
    [city_name] [nvarchar](128) NOT NULL,
    [latitude] [float] NOT NULL,
    [longitude] [float] NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

ip_from 和 ip_to 列是根据 ipv4 地址计算的,如下所示:

return (
      convert(bigint, parsename(@ip, 1)) +
      convert(bigint, parsename(@ip, 2)) * convert(bigint, 256) +
      convert(bigint, parsename(@ip, 3)) * convert(bigint, 65536) +
      convert(bigint, parsename(@ip, 4)) * convert(bigint, 16777216)
    )
Run Code Online (Sandbox Code Playgroud)

然后,我使用使用上述计算转换为 bigint 的 ipv4 地址来搜索 ip 地址位于 ip_from 和 ip_to 列之间的行。

我总是会找到一行,虽然它不是由模式强制执行的,但这是数据中的现实。 …

index sql-server optimization clustered-index nonclustered-index

4
推荐指数
2
解决办法
784
查看次数

即使存在正确的索引,聚合列也会导致全表扫描

我有一个查询,我想从 date_ added 列排序的表数据集中获取前几行。排序依据的列被索引,所以这个表的基本版本非常快:

SELECT datasets.id FROM datasets ORDER BY date_added LIMIT 25
Run Code Online (Sandbox Code Playgroud)

"Limit  (cost=0.28..6.48 rows=25 width=12) (actual time=0.040..0.092 rows=25 loops=1)"
"  ->  Index Scan using datasets_date_added_idx2 on datasets  (cost=0.28..1244.19 rows=5016 width=12) (actual time=0.037..0.086 rows=25 loops=1)"
"Planning time: 0.484 ms"
"Execution time: 0.139 ms"
Run Code Online (Sandbox Code Playgroud)

但是一旦我使查询变得更复杂,我就会遇到问题。我想加入另一个表示多对多关系的表,并将结果聚合在一个数组列中。为此,我需要添加一个 GROUP BY id 子句:

SELECT datasets.id FROM datasets GROUP BY datasets.id ORDER BY date_added LIMIT 25
Run Code Online (Sandbox Code Playgroud)

"Limit  (cost=551.41..551.47 rows=25 width=12) (actual time=9.926..9.931 rows=25 loops=1)"
"  ->  Sort  (cost=551.41..563.95 rows=5016 width=12) (actual time=9.924..9.926 rows=25 loops=1)"
" …
Run Code Online (Sandbox Code Playgroud)

postgresql performance optimization postgresql-9.5 query-performance

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

表变量有主键时对执行计划的影响

在阅读了大量有关 SQL Server 中临时表和表变量之间差异的信息后,我正在尝试从主要使用临时表切换到主要使用表变量。(它们似乎更适合我通常使用的查询类型。)

在这些查询中,表包含驱动查找过程的唯一标识符。在使用临时表时,我的习惯是包含一个PRIMARY KEY约束,以便查询优化器知道它不会看到任何重复项。但是,鉴于优化器(在大多数情况下,对于我的查询)假定表变量仅包含单行*,根据定义这是唯一的,如果存在PRIMARY KEY约束,查询优化器是否会做出任何不同的选择?

* 从技术上讲,它假定没有行,但将零替换为一。(因为零与估计过程的其余部分的交互非常差。)但这也取决于在编译查询时是否填充了表变量。这里有一些背景信息:SQL Server 中的临时表和表变量有什么区别?.

我目前正在使用 SQL Server 2014,但我很好奇新版本的行为是否发生变化。


正如已经指出的那样,PRIMARY KEY约束带有聚集索引,它为查询优化器提供了更多关于如何从表变量中获取数据的选择。我意识到了这一点,并考虑了查询计划的其余部分。但是在试图澄清我的问题之后,我决定我试图提出的问题太广泛了,可能特别针对我的极端情况。(不过是对半万亿行表的导航类型查询,期望达到亚秒级性能。)所以我将保持我的问题不变。

sql-server optimization table-variable

4
推荐指数
2
解决办法
1308
查看次数

左外连接 - 查询计划中的排序操作 - 有什么方法可以调整这个简单的查询?

在处理以下查询以回答此问题时:

如何以数据库不可知的方式查询图表数据?

有以下表格:

CREATE TABLE [dbo].[#foo] ( 
[creation]  DATETIME                         NOT NULL,
[value]     MONEY                                NULL,
[DT]        AS (CONVERT([date],[CREATION])) PERSISTED)


-- add a clustered index on the dt column
CREATE CLUSTERED INDEX CI_FOO ON #FOO(DT)
GO
Run Code Online (Sandbox Code Playgroud)

和另一个加入表:

create table #bar (dt date primary key clustered)
go
Run Code Online (Sandbox Code Playgroud)

可以在此处找到将数据加载到这些表中

但是在运行以下查询时:

WITH RADHE AS (
SELECT THE_ROW=ROW_NUMBER() OVER(PARTITION BY B.DT ORDER BY B.DT),
       THE_DATE=B.dt,
       THE_NUMBER_OF_RECORDS_ON_THIS_DAY=CASE WHEN F.DT IS NULL THEN 0 ELSE COUNT(*) OVER (PARTITION BY F.DT ) END ,
       THE_TOTAL_VALUE_FOR_THE_DAY=COALESCE(SUM(F.VALUE) OVER (PARTITION BY …
Run Code Online (Sandbox Code Playgroud)

performance sql-server optimization execution-plan sort-operator query-performance

4
推荐指数
2
解决办法
1286
查看次数