简体   繁体   English

PostgreSQL模拟SQL Server索引(包括列)

[英]PostgreSQL analog of SQL Server index(include columns)

Trying to recreate my SQL Server database on PostgreSQL. 试图在PostgreSQL上重新创建我的SQL Server数据库。 Everything is ok except I can't find how to recreate this index: 一切都很好,除了我找不到如何重新创建这个索引:

USE [mytablename]  
GO  
CREATE NONCLUSTERED INDEX [myindex]  
ON [dbo].[mytablename] ([col1],[col2])  
INCLUDE ([col3],[col4])  
GO  

Will be very grateful for help. 将非常感谢您的帮助。

Alexey 阿列克谢

Update: 更新:

http://img38.imageshack.us/img38/1071/89013974.png here is db structure star+eav http://img38.imageshack.us/img38/1071/89013974.png这里是db structure star + eav
there is only one query 只有一个查询

SELECT this_.id as id0_0_,   
this_.device_id as device2_0_0_,  
this_.time_id as time3_0_0_,  
this_.gps_detail_id as gps4_0_0_   
FROM [scoutserver_data].[dbo].[DataMessage]  this_   
WHERE this_.time_id = 65536 and this_.device_id = 32768  

Maybe it is not optimal atm. 也许它不是最佳的atm。 And im working on it also. 我正在研究它。 Maybe something like this 也许这样的事情

SELECT * FROM [scoutserver_data].[dbo].[TimeDimension]   
  INNER JOIN ([scoutserver_data].[dbo].[DeviceDimension]   
  INNER JOIN  [scoutserver_data].[dbo].[DataMessage]   
ON [DeviceDimension].[device_id] =[DataMessage].[device_id])  
ON [TimeDimension].[time_id] = [DataMessage].[time_id]  
WHERE DeviceDimension.serial_id='2' AND TimeDimension.Day=15 AND TimeDimension.Year=2009

Any hints welcome =) 任何提示欢迎=)

CREATE INDEX myindex ON mytablename (co1l, col2, col3, col4)

PostgreSQL does not support clustered or covering indexes. PostgreSQL不支持聚簇或覆盖索引。

Update: 更新:

For this query, you'll need to create the suggested index indeed: 对于此查询,您需要确实创建建议的索引:

SELECT  this_.id as id0_0_,   
        this_.device_id as device2_0_0_,  
        this_.time_id as time3_0_0_,  
        this_.gps_detail_id as gps4_0_0_   
FROM    DataMessage this_   
WHERE   this_.time_id = 65536
        AND this_.device_id = 32768

CREATE INDEX ix_datamessage_time_device_id_detail ON datamessage (time_id, device_id, id, gps_detail_id)

However, your tables seem to be over-normalized to me. 但是,您的表似乎对我来说过度标准化了。

You can keep year, month and day in a single INT field in your table. 您可以将年,月和日保存在表中的单个INT字段中。 This will save you a join. 这将为您节省一次加入。

There might be the point of keeping DataMessage and GpsDetails in separate tables if either GpsDetails are rarely linked to the DataMessage (this is, gps_details_id is often set to NULL ), or a GPS details record can be shared between multiple data messages. 如果GpsDetails很少链接到DataMessage (这是gps_details_id通常设置为NULL ),或者可以在多个数据消息之间共享GPS详细信息记录,则可能需要将DataMessageGpsDetails在单独的表中。

It it's not, it will be better to move the GPS details into the data messages table. 它不是,将GPS细节移动到数据消息表中会更好。

PostgreSQL 11 supports included columns. PostgreSQL 11支持包含的列。 Excerpt from Waiting for PostgreSQL 11 – Indexes with INCLUDE columns and their support in B-tree : 摘自等待PostgreSQL 11 - 包含INCLUDE列的索引及其在B-tree中的支持

This patch introduces INCLUDE clause to index definition. 此修补程序将INCLUDE子句引入索引定义。 This clause specifies a list of columns which will be included as a non-key part in the index. 此子句指定列的列表,这些列将作为索引中的非键部分包含在内。 The INCLUDE columns exist solely to allow more queries to benefit from index-only scans. INCLUDE列仅用于允许更多查询从仅索引扫描中受益。 Also, such columns don't need to have appropriate operator classes. 此外,此类列不需要具有适当的运算符类。 Expressions are not supported as INCLUDE columns since they cannot be used in index-only scans. INCLUDE列不支持表达式,因为它们不能用于仅索引扫描。

For now, only B-tree indexes support INCLUDE clause. 目前,只有B树索引支持INCLUDE子句。

CREATE INDEX myindex ON mytablename (col1,col2) INCLUDE (col3,col4); 

EDIT: 编辑:

CREATE INDEX : 创建指数

[ INCLUDE ( column_name [, ...] ) ] [INCLUDE(column_name [,...])]

The optional INCLUDE clause specifies a list of columns which will be included in the index as non-key columns. 可选的INCLUDE子句指定将作为非键列包含在索引中的列列表。 A non-key column cannot be used in an index scan search qualification, and it is disregarded for purposes of any uniqueness or exclusion constraint enforced by the index. 非键列不能用于索引扫描搜索限定,并且出于索引强制执行的任何唯一性或排除约束的目的,它将被忽略。 However, an index-only scan can return the contents of non-key columns without having to visit the index's table, since they are available directly from the index entry. 但是,仅索引扫描可以返回非键列的内容,而不必访问索引表,因为它们可以直接从索引条目中获得。 Thus, addition of non-key columns allows index-only scans to be used for queries that otherwise could not use them. 因此,添加非键列允许仅索引扫描用于否则无法使用它们的查询。

Columns listed in the INCLUDE clause don't need appropriate operator classes; INCLUDE子句中列出的列不需要适当的运算符类; the clause can include columns whose data types don't have operator classes defined for a given access method. 该子句可以包括其数据类型没有为给定访问方法定义的运算符类的列。

Expressions are not supported as included columns since they cannot be used in index-only scans. 列表不支持表达式,因为它们不能用于仅索引扫描。

Currently, only the B-tree index access method supports this feature. 目前,只有B树索引访问方法支持此功能。 In B-tree indexes, the values of columns listed in the INCLUDE clause are included in leaf tuples which correspond to heap tuples, but are not included in upper-level index entries used for tree navigation. 在B树索引中,INCLUDE子句中列出的列的值包含在与元组对应的叶元组中,但不包括在用于树导航的上层索引条目中。

Support for index-only scanning has now been added to the beta version of PostgreSQL. PostgreSQL的beta版本现在已经添加了对仅索引扫描的支持。 It means that if an index contains the columns requested in a query, it likely won't need to go to the underlying data. 这意味着如果索引包含查询中请求的列,则可能不需要转到基础数据。 Index-only scanning happens automatically. 仅索引扫描会自动进行。

Index-only scanning is the main reason for using Included Columns. 仅索引扫描是使用包含列的主要原因。 I don't think postgres (beta or otherwise) supports included columns, so the desired columns will need to be added to the end of the list of columns to index, instead. 我不认为postgres(beta或其他)支持包含的列,因此需要将所需的列添加到要编制索引的列的末尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM