我们的 MySQL 数据库将包含一个百科全书。百科全书将显示在每个页面都包含从一个字母开始的条目的页面中。
我应该使用哪些索引?我应该为字段“标题”设置两个索引(一个长度为 255 的索引用于排序,一个长度为 1 的索引用于按第一个字母进行索引)?
创建表`cyclopedy`( `id` int(10) unsigned NOT NULL auto_increment, `title` varchar(255) 整理 utf8_bin NOT NULL, `article` mediumtext collate utf8_bin NOT NULL, 主键(`id`), KEY `title` (`title`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
好吧,现在我明白长度 1 不足以按第一个字母进行索引,因为 UTF-8 字母可能由三个字节组成。
我有以下定义:
CREATE TABLE [dbo].[JobItems] (
[ItemId] UNIQUEIDENTIFIER NOT NULL,
[ItemState] INT NOT NULL,
[ItemCreationTime] DATETIME NULL DEFAULT GETUTCDATE(),
[ItemPriority] TINYINT NOT NULL DEFAULT(0),
[ItemRefreshTime] DATETIME NULL,
-- lots of other columns
CONSTRAINT [PrimaryKey_GUID_HERE] PRIMARY KEY NONCLUSTERED ([ItemId] ASC)
);
CREATE UNIQUE CLUSTERED INDEX [JobItemsIndex]
ON [dbo].[JobItems]([ItemId] ASC);
CREATE INDEX [GetTaskToProcessIndex]
ON [dbo].[JobItems]([ItemState], [ItemPriority], [ItemCreationTime])
Run Code Online (Sandbox Code Playgroud)
以及以下查询:
SELECT TOP(1) ItemId FROM JobItems
WHERE ItemState = 5 OR
( ( ItemState = 11 ) AND ( DATEDIFF( SECOND, ItemRefreshTime, GETUTCDATE() ) > 14 …Run Code Online (Sandbox Code Playgroud) 对于所有这些查询:
SELECT label FROM personal.storage_disks ORDER BY label ASC;
SELECT label FROM personal.storage_disks ORDER BY label COLLATE "C" ASC;
SELECT label FROM personal.storage_disks ORDER BY label COLLATE "POSIX" ASC;
SELECT label FROM personal.storage_disks ORDER BY label COLLATE "default" ASC;
Run Code Online (Sandbox Code Playgroud)
输出总是:DISK 1, DISK 10, DISK 2, DISK 3, [...]
但是,我想要并期望:DISK 1, DISK 2, DISK 3, [...] DISK 10
我现在没有根据SELECT * FROM pg_collation;......尝试的排序规则,除非我应该使用具有神秘名称的许多非常奇怪的排序规则之一。(我什至尝试了一堆结果相同的方法。)
请注意,我已经阅读了现有的看似相关的 SE 问题以及许多关于 的文章SORT BY,但它们没有帮助,也没有为我清除任何内容。
我正在使用 PostgreSQL 12.4
我正在使用 Oracle sqlplus。我有以下查询:
SELECT fooID from foo MINUS
SELECT fooID from bar;
Run Code Online (Sandbox Code Playgroud)
我创建了两个非聚集 B+ 树索引。一个在fooID表的字段中foo,一个在表的字段fooID中bar。之后,我分析了两个表的统计信息:foo并bar使用EXPLAIN PLAN .... 但我明白了:
SELECT STATEMENT
MINUS
SORT UNIQUE
INDEX FAST FULL SCAN FOO_INDEX
SORT UNIQUE
INDEX FAST FULL SCAN BAR_INDEX
Run Code Online (Sandbox Code Playgroud)
这怎么可能呢?做的时候INDEX FAST FULL SCAN,因为索引是 B+ 树,系统不会取回它的元组排序吗?为什么需要这样做SORT UNIQUE(数据已经排序)?
我还没有找到表索引对表操作的算法顺序的影响的明确指示。
我对具体实现的细节不感兴趣;我假设 RDMS 设计人员知道他们在做什么,并且他们已经尽可能提高了效率。
我将把我的讨论限制在单个索引上,我认为额外的索引只是添加了一个额外的维度(即基本过程必须执行多次)。
下面假设每种情况下只有一条记录 - 索引的好处对于多个记录操作大大增强,因为(通常)查找操作需要执行的次数少于正在查找的记录数,因为它们可以在一个范围内检索。
对于未索引的表,我认为操作是:
Step INSERT SELECT DELETE UPDATE
Find the record N/A O(n) O(n) O(n)
Modify the record O(1) N/A O(1) O(1)
OVERALL O(1) O(n) O(n) O(n)
Run Code Online (Sandbox Code Playgroud)
这假设查找记录需要表扫描,但新记录只是简单地放在末尾。
建立索引是一个基于高效排序算法的 O(nlog(n)) 操作。
对于索引表,我相信操作是:
Step INSERT SELECT DELETE UPDATE
Find the record N/A O(log(n)) O(log(n)) O(log(n))
Modify the record O(1) N/A O(1) O(1)
Update the index O(log(n)) N/A O(1) O(1)
OVERALL O(log(n)) O(log(n)) O(log(n)) O(log(n))
Run Code Online (Sandbox Code Playgroud)
这假设现在查找记录是对索引的有序查找操作,更新索引是一个步骤DELETE和UPDATE(因为您已经找到了记录)和一个有序查找INSERT
也就是说,插入变得更糟,但其他一切都变得更好。
这样对吗?
我们最近使用较新版本的 Oracle (12c) 而不是 11r2 部署了一个新环境。
直到最近我才注意到我返回的数据的排序方式不同。
而不是有小写字母、大写字母和数字......(在 Oracle 11r2 上)我以相反的方式对我的数据进行排序:数字、大写字母、小写字母(Oracle 12c)
这确实让查询数据库的各种应用程序的最终用户感到困惑。我需要检查/比较哪些设置才能在 Oracle 12c 中解决此问题?
我提到的查询有一个 order by 子句。 编辑 这些参数的设置在两个环境上是相同的:
NLS_SORT 类型:字符串值:
nls_language 类型:字符串值:DUTCH
所以 NLS_SORT 没有值,那么默认值是多少?
@菲尔
select * from NLS_INSTANCE_PARAMETERS;
Parameter Oracle11r2 Oracle12c
NLS_LANGUAGE DUTCH DUTCH
NLS_TERRITORY THE NETHERLANDS THE NETHERLANDS
NLS_SORT
NLS_DATE_LANGUAGE
NLS_DATE_FORMAT
NLS_CURRENCY
NLS_NUMERIC_CHARACTERS
NLS_ISO_CURRENCY
NLS_CALENDAR
NLS_TIME_FORMAT
NLS_TIMESTAMP_FORMAT
NLS_TIME_TZ_FORMAT
NLS_TIMESTAMP_TZ_FORMAT
NLS_DUAL_CURRENCY
NLS_COMP BINARY BINARY
NLS_LENGTH_SEMANTICS BYTE CHAR
NLS_NCHAR_CONV_EXCP FALSE FALSE
select * from NLS_SESSION_PARAMETERS;
these are the same as my NLS settings in Oracle …Run Code Online (Sandbox Code Playgroud) 假设我有一列 x 的值是 A 和 B。例如:
Row X
1 A
2 A
3 A
4 B
5 B
6 B
Run Code Online (Sandbox Code Playgroud)
现在,我想将它们分类为这种方式:
Row X
1 A
2 B
3 A
4 B
5 A
6 B
Run Code Online (Sandbox Code Playgroud)
当然,我可以新建一个 Column Y。然后将 A 行分配给奇数 (1, 3, 5, ...),将 B 行分配给偶数 (2, 4, 6, ...),然后按 Y 列排序。但是有没有更简单的方法来实现这一目标?
如果答案可以与 MS SQL 一起使用,那将是最好的。
我想测试 tempdb 溢出警告,所以我在 SQL Server 2014 上运行以下脚本:
USE tempdb
IF OBJECT_ID('tempdb..tblTest') IS NOT NULL DROP TABLE tblTest
CREATE TABLE tblTest
(
c1 INT PRIMARY KEY CLUSTERED,
c2 INT ,
c3 CHAR (1000)
);
GO
SET NOCOUNT ON;
BEGIN TRANSACTION;
DECLARE @i AS INT;
SET @i = 1;
WHILE @i <= 10000
BEGIN
INSERT INTO tblTest (c1, c2, c3)
VALUES (@i, @i, 'a');
SET @i = @i + 1;
END
COMMIT TRANSACTION;
GO
UPDATE STATISTICS dbo.tblTest
GO
SET STATISTICS XML ON; …Run Code Online (Sandbox Code Playgroud) sql-server optimization sorting sql-server-2014 query-performance
我正在尝试优化查询以更快地运行。查询如下:
SELECT grp_fk_obj_id, grp_name
FROM tbl_groups as g1
CROSS APPLY (SELECT TOP 1 grp_id as gid
FROM tbl_groups as g2
WHERE g1.grp_fk_obj_id = g2.grp_fk_obj_id
ORDER BY g2.date_from DESC, ISNULL(date_to, '4000-01-01') DESC) as a
WHERE g1.grp_id = gid
Run Code Online (Sandbox Code Playgroud)
grp_id 是主键。grp_fk_obj_id 是另一个对象的外键。这两列都有索引(我猜它是默认的)。
完成大约需要半秒钟,但我需要它来加快工作速度。我查看了执行计划,它显示“Top N 排序”的成本超过 90%。另外,我注意到,如果我删除了交叉应用中的 where 子句,那么它的运行速度至少要快 5 倍,但我需要以一种或另一种方式使用 where 子句。
您是否认为有可能提高此查询的性能?
编辑:表创建 DDL:
create table tbl_groups
(
grp_id bigint identity
constraint PK_tbl_groups
primary key,
grp_fk_obj_id bigint not null
constraint FK_grp_fk_obj_id
references tbl_other,
grp_name varchar(30) not null,
date_from date not null, …Run Code Online (Sandbox Code Playgroud) 我有一个返回所需输出的查询。
SELECT
shop,
JSON_AGG(item_history.* ORDER BY created_date DESC) as data
FROM item_history
GROUP BY
shop;
Run Code Online (Sandbox Code Playgroud)
结果:
[
{
"shop": "shop1",
"data": [
{
"id": 226,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item1",
"created_date": "2021-06-07T08:48:42.338201",
},
{
"id": 224,
"price": "0",
"shop": "shop1.com",
"country": "UK",
"item": "item 1",
"created_date": "2021-06-07T07:53:25.030621",
},
...
},
{
"shop": "shop2",
"data": [
{
"id": 225,
"price": "0",
"shop": "shop2.com",
"country": "DE",
"item": "Item 2",
"created_date": "2021-06-07T08:48:36.443849",
},
...
]
Run Code Online (Sandbox Code Playgroud)
这正是我想要的输出,但问题是它获取data数组下的所有项目,最好限制该数组。我尝试添加LIMIT
SELECT …Run Code Online (Sandbox Code Playgroud) sorting ×10
sql-server ×4
index ×2
natural-sort ×2
postgresql ×2
collation ×1
cross-apply ×1
explain ×1
group-by ×1
index-tuning ×1
innodb ×1
limits ×1
mysql ×1
optimization ×1
oracle ×1
oracle-11g ×1
oracle-12c ×1
order-by ×1
sqlplus ×1
top ×1