【问题标题】:PostgreSQL analog of SQL Server index(include columns)SQL Server 索引的 PostgreSQL 模拟(包括列)
【发布时间】:2010-12-11 14:47:12
【问题描述】:

尝试在 PostgreSQL 上重新创建我的 SQL Server 数据库。一切都很好,除了我找不到如何重新创建这个索引:

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

非常感谢您的帮助。

阿列克谢

更新:

http://img38.imageshack.us/img38/1071/89013974.png这里是db结构star+eav
只有一个查询

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  

也许它不是最佳atm。我也在努力。也许是这样的

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

欢迎任何提示 =)

【问题讨论】:

    标签: sql sql-server database-design postgresql database


    【解决方案1】:

    PostgreSQL 11 支持包含列。摘自Waiting for PostgreSQL 11 – Indexes with INCLUDE columns and their support in B-tree

    此补丁在索引定义中引入了 INCLUDE 子句。本条款 指定列的列表,这些列将作为非关键部分包含在 索引。 INCLUDE 列的存在只是为了允许更多查询 受益于仅索引扫描。此外,这样的列不需要有 适当的运算符类。不支持将表达式作为 INCLUDE 列,因为它们不能用于仅索引扫描。

    目前,只有 B-tree 索引支持 INCLUDE 子句。

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

    编辑:

    CREATE INDEX:

    [ 包括(列名 [, ...] )]

    可选的 INCLUDE 子句指定一个列列表,这些列将被 作为非键列包含在索引中。非键列不能 用于索引扫描搜索限定,它被忽略 执行的任何唯一性或排除约束的目的 指数。但是,仅索引扫描可以返回非键的内容 列而不必访问索引的表,因为它们是 可直接从索引条目中获得。 因此,添加非键 列允许仅索引扫描用于查询,否则 无法使用它们。

    INCLUDE 子句中列出的列不需要适当的运算符类;该子句可以包括其数据类型的列 没有为给定的访问方法定义运算符类。

    不支持将表达式作为包含列,因为它们不能用于仅索引扫描。

    目前只有 B-tree 索引访问方式支持此功能。 在 B-tree 索引中,列在 INCLUDE 子句包含在对应于堆的叶元组中 元组,但不包含在用于 树形导航。

    【讨论】:

      【解决方案2】:
      CREATE INDEX myindex ON mytablename (co1l, col2, col3, col4)
      

      PostgreSQL 不支持聚集索引或覆盖索引。

      更新:

      对于这个查询,您确实需要创建建议的索引:

      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)
      

      但是,对我来说,您的表格似乎过于规范化。

      您可以将年、月和日保存在表中的单个 INT 字段中。这将为您节省加入。

      如果GpsDetails 很少链接到DataMessage(即gps_details_id 通常设置为NULL),则可能需要将DataMessageGpsDetails 保存在单独的表中,或者GPS 详细信息记录可以在多条数据消息之间共享。

      不是这样,最好把 GPS 详细信息移到数据消息表中。

      【讨论】:

      • 索引会妨碍DML 的性能并加快可搜索查询的速度。除非我看到您的表结构和查询,否则很难判断。
      • 然后在所有四列上创建索引,如帖子中所述。这与SQL Server 中的覆盖索引几乎相同,只是idgps_detail_id 是索引键的一部分,而不是索引数据。这仅对DML 和密钥查找时间很重要。范围扫描将是相同的。但是请注意,PostgreSQL 在遍历索引方面比SQL Server 慢得多。
      • @cdhowie:是什么让你认为这个命令会创建聚集索引?
      • @cdhowie:它没有。它只是对堆进行重新排序并标记索引,以便您下次执行CLUSTER 时可以省略USING index_name 部分。在您对表执行INSERTUPDATE 后,堆仍然是一个堆,并且不会维护其顺序。使用聚集索引,所有表数据都存储在B-Tree 或其他保持顺序的结构中。
      • @cdhowie:如果您查看问题标题,您会很容易找到在哪里寻找正确的定义。 PostgreSQL 不支持聚集索引:它不能将表记录存储在B-Tree 或任何其他顺序维护结构中;它不会保留“聚集”后的记录顺序;即使在运行CLUSTER 命令之后,它也不能依赖记录的顺序(您仍然会在计划中看到sort)。不要被一个叫做CLUSTER的命令所迷惑:不同的数据库调用这个完全不相关的东西。
      【解决方案3】:

      PostgreSQL 测试版现已添加对仅索引扫描的支持。这意味着如果索引包含查询中请求的列,它可能不需要转到基础数据。仅索引扫描会自动发生。

      仅索引扫描是使用包含列的主要原因。我不认为 postgres(测试版或其他)支持包含的列,因此需要将所需的列添加到要索引的列列表的末尾。

      【讨论】:

      • 值得注意的是,如果页面自上次 VACUUM 以来已被修改,则在 9.2 中添加的仅索引扫描仍需要在数据中查找。
      • PostgreSQL 11 将支持include columns
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2016-03-07
      • 1970-01-01
      相关资源
      最近更新 更多