JSON索引比具有相同值的文本列上的索引慢得多

时间:2018-07-19 23:07:10

标签: postgresql jsonb postgresql-9.5

我有一个索引:CREATE INDEX index_c_profiles_on_city_state_name_domain ON c_profiles ((data->>'state'), (data->>'city'), name, domain);

和另一个索引:CREATE INDEX index_c_profiles_on_state ON c_profiles (state),我创建了一个名为'state'的新列,其中data->>'state'的值是从jsonb列中手动复制的每一行

我尝试使用以下查询来使用第一个索引:SELECT mm.name, mm.domain, mm.data ->> 'city' as city, mm.data ->> 'state' as state FROM c_profiles as mm WHERE ((mm.data ->> 'state') = 'CA'),并且花了8秒钟来完成

[
  {
    "Execution Time": 8023.687,
    "Planning Time": 0.5,
    "Plan": {
      "Exact Heap Blocks": 16743,
      "Node Type": "Bitmap Heap Scan",
      "Actual Total Time": 8014.769,
      "Shared Hit Blocks": 2523,
      "Schema": "public",
      "Plans": [
        {
          "Node Type": "Bitmap Index Scan",
          "Actual Total Time": 94.311,
          "Shared Hit Blocks": 3,
          "Shared Read Blocks": 350,
          "Temp Written Blocks": 0,
          "Local Dirtied Blocks": 0,
          "Local Hit Blocks": 0,
          "Plan Width": 0,
          "Actual Loops": 1,
          "Actual Startup Time": 94.311,
          "Temp Read Blocks": 0,
          "Local Read Blocks": 0,
          "Index Name": "index_c_profiles_on_city_state_name_domain",
          "Startup Cost": 0,
          "Shared Dirtied Blocks": 0,
          "Shared Written Blocks": 0,
          "Local Written Blocks": 0,
          "Plan Rows": 21870,
          "Index Cond": "((mm.data ->> 'state'::text) = 'CA'::text)",
          "Actual Rows": 21729,
          "Parent Relationship": "Outer",
          "Total Cost": 1604.45
        }
      ],
      "Shared Read Blocks": 17472,
      "Relation Name": "c_profiles",
      "Local Hit Blocks": 0,
      "Local Dirtied Blocks": 0,
      "Temp Written Blocks": 0,
      "Plan Width": 980,
      "Actual Loops": 1,
      "Rows Removed by Index Recheck": 0,
      "Lossy Heap Blocks": 0,
      "Alias": "mm",
      "Recheck Cond": "((mm.data ->> 'state'::text) = 'CA'::text)",
      "Temp Read Blocks": 0,
      "Output": [
        "(data ->> 'city'::text)",
        "(data ->> 'state'::text)"
      ],
      "Actual Startup Time": 99.44,
      "Local Read Blocks": 0,
      "Startup Cost": 1609.91,
      "Shared Dirtied Blocks": 360,
      "Shared Written Blocks": 0,
      "Local Written Blocks": 0,
      "Plan Rows": 21870,
      "Actual Rows": 21537,
      "Total Cost": 42388.85
    },
    "Triggers": []
  }
]

然后,我尝试使用该查询使用第二个索引:SELECT state FROM mattermark_profiles as mm WHERE state = 'CA',并且花费了20毫秒的时间

    [
  {
    "Execution Time": 20.19,
    "Planning Time": 0.5,
    "Plan": {
      "Node Type": "Index Only Scan",
      "Actual Total Time": 16.206,
      "Shared Hit Blocks": 633,
      "Schema": "public",
      "Scan Direction": "Forward",
      "Shared Read Blocks": 59,
      "Relation Name": "c_profiles",
      "Local Hit Blocks": 0,
      "Heap Fetches": 776,
      "Local Dirtied Blocks": 0,
      "Temp Written Blocks": 0,
      "Plan Width": 3,
      "Actual Loops": 1,
      "Rows Removed by Index Recheck": 0,
      "Actual Startup Time": 0.08,
      "Alias": "mm",
      "Temp Read Blocks": 0,
      "Output": [
        "state"
      ],
      "Local Read Blocks": 0,
      "Index Name": "index_c_profiles_on_state",
      "Startup Cost": 0.42,
      "Shared Dirtied Blocks": 53,
      "Shared Written Blocks": 0,
      "Local Written Blocks": 0,
      "Plan Rows": 21870,
      "Index Cond": "(mm.state = 'CA'::text)",
      "Actual Rows": 21524,
      "Total Cost": 639.12
    },
    "Triggers": []
  }
]

由于两个输出都是相同的行,为什么JSON索引的性能如此差?由于数据和行数是相同的,因此似乎必须有一种方法可以通过JSON索引获得相似的结果,但是我不清楚如何实现。任何帮助将不胜感激!

0 个答案:

没有答案