সংমিশ্রিত সূচকগুলি: সর্বাধিক নির্বাচনী কলামটি প্রথম?


17

আমি পড়ছিলাম composite indexesএবং অর্ডার সম্পর্কে আমি কিছুটা বিভ্রান্ত। এই ডকুমেন্টেশন (অর্ধেক রাস্তা নিচে কিছুটা কম) বলেছেন

সাধারণভাবে, আপনার সূচীতে বেশিরভাগ ক্ষেত্রে ব্যবহৃত কলামটি প্রত্যাশিত হওয়া উচিত।

তবে এর পরেই তা বলা হয়েছে

সর্বাধিক নির্বাচনী কলামটি রেখে একটি যৌগিক সূচক তৈরি করুন; যে, সর্বাধিক মান সহ কলাম।

ওরাকল এটিকে এখানে অন্য কথায় বলে

যদি সমস্ত কীগুলি WHERE ক্লজগুলিতে সমানভাবে প্রায়শই ব্যবহৃত হয়, তবে ক্রিয়েট ইনডেক্সের বিবৃতিতে সর্বাধিক নির্বাচিত থেকে কমপক্ষে নির্বাচক থেকে এই কীগুলি অর্ডার করা ক্যোরির কার্যকারিতা উন্নত করে।

তবে, আমি একটি এসও উত্তর পেয়েছি যা আলাদাভাবে বলে। এটা বলে

প্রথমে সর্বনিম্ন নির্বাচনী কলাম এবং সর্বাধিক নির্বাচনী কলাম সহ কলামগুলি সাজান। কলামের সাথে টাই সীসার ক্ষেত্রে এটি নিজের ব্যবহারের সম্ভাবনা বেশি।

আমি উল্লেখ করা প্রথম ডকুমেন্টেশন বলছে যে আপনাকে প্রথমে সর্বাধিক ব্যবহার করা উচিত যেখানে এসও উত্তর বলে যে এটি কেবল টাই ব্রেকিংয়ের জন্য হওয়া উচিত। তারপরে তারা অর্ডার দেওয়ার ক্ষেত্রেও আলাদা হয়।

এই ডকুমেন্টেশন সম্পর্কেও skip scanningকথা বলে এবং বলে

সম্মিলিত সূচকের শীর্ষস্থানীয় কলামে কয়েকটি স্বতন্ত্র মান এবং সূচকের ননলেডিং কীতে অনেক স্বতন্ত্র মান থাকলে স্কিপ স্ক্যানিং সুবিধাজনক।

আর একটি নিবন্ধ বলেছে

উপসর্গ কলামটি সবচেয়ে বৈষম্যমূলক এবং প্রশ্নগুলিতে সর্বাধিক ব্যবহৃত হওয়া উচিত

আমি বিশ্বাস করি যে সর্বাধিক বৈষম্যমূলক আচরণটির অর্থ সবচেয়ে স্বতন্ত্র।

এই সমস্ত গবেষণা এখনও আমাকে একই প্রশ্নের দিকে নিয়ে যায়; সর্বাধিক নির্বাচনী কলামটি প্রথম বা শেষ হওয়া উচিত? টাই-ব্রেকের ক্ষেত্রে প্রথম কলামটি সবচেয়ে বেশি ব্যবহৃত এবং কেবল সবচেয়ে বেশি নির্বাচনী হওয়া উচিত?

এই নিবন্ধগুলি একে অপরের বিরোধিতা করছে বলে মনে হচ্ছে তবে তারা কিছু উদাহরণ দেয়। আমি যা জড়ো করেছি সেগুলি least selective columnথেকে, আপনি যদি প্রত্যাশা করছেন তবে ক্রমটি প্রথম হওয়ার পক্ষে এটি আরও কার্যকর Index Skip Scans। তবে আমি সঠিক তা নিশ্চিত কিনা।


উত্তর:


8

আস্কটম থেকে

(9 আই-তে, একটি নতুন "ইনডেক্স স্কিপ স্ক্যান" রয়েছে - এটি পড়ার জন্য সেখানে অনুসন্ধান করুন It এটি সূচকটি (ক, খ) বা (খ, ক) উপরের উভয় ক্ষেত্রে দরকারী করে তোলে!)

সুতরাং, আপনার সূচীতে কলামগুলির ক্রম নির্ভর করে আপনার প্রশ্নগুলি কীভাবে লেখা হয়। আপনি যতটা ক্যোয়ারির জন্য সূচকটি ব্যবহার করতে সক্ষম হতে চান (যাতে আপনার যতগুলি সংখ্যক সূচকে ছাড়িয়ে যায়) - এটি কলামগুলির ক্রমকে চালিত করবে। আর কিছুই নয় (a বা b এর সিলেক্টিভিটি মোটেই গণ্য হয় না)।

কমপক্ষে বৈষম্যমূলক (কম স্বতন্ত্র মান) থেকে সর্বাধিক বৈষম্যমূলক (আরও স্বতন্ত্র মান) এর জন্য কমপোজেট ইনডেক্সে কলামগুলি সাজানোর পক্ষে যুক্তিগুলির একটি হ'ল সূচি কী সংকোচনের জন্য।

SQL> create table t as select * from all_objects;

Table created.

SQL> create index t_idx_1 on t(owner,object_type,object_name);

Index created.

SQL> create index t_idx_2 on t(object_name,object_type,owner);

Index created.

SQL> select count(distinct owner), count(distinct object_type), count(distinct object_name ), count(*)  from t;

COUNT(DISTINCTOWNER) COUNT(DISTINCTOBJECT_TYPE) COUNT(DISTINCTOBJECT_NAME)      COUNT(*)
-------------------- -------------------------- --------------------------      ----------
                 30                         45                       52205      89807

SQL> analyze index t_idx_1 validate structure; 

Index analyzed.

SQL> select btree_space, pct_used, opt_cmpr_count, opt_cmpr_pctsave from index_stats;

BTREE_SPACE   PCT_USED OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
----------- ---------- -------------- ----------------
    5085584     90          2           28

SQL> analyze index t_idx_2 validate structure; 

Index analyzed.

SQL> select btree_space, pct_used, opt_cmpr_count, opt_cmpr_pctsave  from index_stats; 

BTREE_SPACE   PCT_USED OPT_CMPR_COUNT OPT_CMPR_PCTSAVE
----------- ---------- -------------- ----------------
    5085584     90          1           14

সূচকের পরিসংখ্যান অনুসারে, প্রথম সূচকটি আরও সংকোচনের।

অন্যটি হ'ল সূচিটি কীভাবে আপনার প্রশ্নগুলিতে ব্যবহৃত হয়। যদি আপনার প্রশ্নগুলি বেশিরভাগ ব্যবহার করেcol1 ,

উদাহরণস্বরূপ, আপনার যদি প্রশ্ন থাকে তবে-

  • select * from t where col1 = :a and col2 = :b;
  • select * from t where col1 = :a;

    -then index(col1,col2) আরও ভাল পারফর্ম করতে হবে।

    আপনার প্রশ্ন বেশিরভাগই ব্যবহার করেন তাহলে col2,

  • select * from t where col1 = :a and col2 = :b;
  • select * from t where col2 = :b;

    -then index(col2,col1) আরও ভাল পারফর্ম করতে হবে। যদি আপনার সমস্ত প্রশ্নের সবসময় উভয় কলাম নির্দিষ্ট করে থাকে তবে কোন কলামটি যৌগিক সূচীতে প্রথমে আসে তা বিবেচনা করে না।

    উপসংহারে, সংমিশ্রিত সূচকের কলাম ক্রমের মূল বিবেচ্য বিষয়গুলি হ'ল সূচি কী সংকোচনের বিষয়টি এবং কীভাবে আপনি আপনার অনুসন্ধানগুলিতে এই সূচকটি ব্যবহার করতে যাচ্ছেন।

    তথ্যসূত্র:

  • সূচীতে কলাম ক্রম
  • কোনও সূচক (ডান) তে নিম্ন কার্ডিনালিটি শীর্ষস্থানীয় কলামগুলি রাখার পক্ষে কম দক্ষ?
  • সূচক স্কিপ স্ক্যান - সূচী কলাম কি আর কোনও বিষয়ে গুরুত্বপূর্ণ? (সতর্কীকরণ চিহ্ন)


  • 3

    এই কলামটি যখন আসল WHERE ধারাতে থাকবে কেবল তখনই বেশিরভাগ নির্বাচনী কার্যকর হয় useful

    যখন নির্বাচন বৃহত্তর গোষ্ঠী দ্বারা হয় (কম নির্বাচক), এবং তারপরে সম্ভবত অন্যান্য, অন-সূচকযুক্ত মানগুলি দ্বারা, কম নির্বাচিত কলামগুলির সাথে একটি সূচকটি এখনও কার্যকর হতে পারে (যদি অন্যটি তৈরি না করার কারণ থাকে)।

    সাথে যদি কোনও টেবিলের ঠিকানা থাকে with

    দেশ সিটি স্ট্রিট, অন্য কিছু ...

    স্ট্রিট, সিটি, COUNTRY সূচী দিয়ে রাস্তার নামের সাথে দ্রুততম কোয়েরি তৈরি হবে। তবে কোনও শহরের সমস্ত রাস্তায় জিজ্ঞাসাবাদ করা, সূচকটি অকেজো হবে এবং কোয়েরিটি সম্ভবত একটি পূর্ণ টেবিল স্ক্যান করবে।

    তালিকাভুক্ত দেশ, সিটি, স্ট্রিট পৃথক রাস্তাগুলির জন্য কিছুটা ধীর হতে পারে তবে সূচিটি অন্য প্রশ্নের জন্য ব্যবহার করা যেতে পারে, কেবল দেশ এবং / অথবা শহর দ্বারা নির্বাচন করে।


    3

    সূচী কলাম ক্রম নির্বাচন করার সময়, ওভাররাইডিং উদ্বেগটি হ'ল:

    আমার প্রশ্নের মধ্যে এই কলামের বিরুদ্ধে (সমতা) পূর্বাভাস আছে?

    যদি কোনও কলামটি যেখানে কোনও ধারায় উপস্থিত না হয়, তবে এটি সূচকের (1) মূল্যবান নয়

    ঠিক আছে, সুতরাং আপনি প্রতিটি কলামের বিরুদ্ধে একটি টেবিল এবং ক্যোয়ারী পেয়েছেন। কখনও কখনও একাধিক।

    কীভাবে সূচকে সিদ্ধান্ত নেবেন?

    একটি উদাহরণ তাকান। এখানে তিনটি কলাম সহ একটি টেবিল। একটিতে 10 টি মান রয়েছে, অন্যটি 1000, শেষ 10,000:

    create table t(
      few_vals  varchar2(10),
      many_vals varchar2(10),
      lots_vals varchar2(10)
    );
    
    insert into t 
    with rws as (
      select lpad(mod(rownum, 10), 10, '0'), 
             lpad(mod(rownum, 1000), 10, '0'), 
             lpad(rownum, 10, '0') 
      from dual connect by level <= 10000
    )
      select * from rws;
    
    commit;
    
    select count(distinct few_vals),
           count(distinct many_vals) ,
           count(distinct lots_vals) 
    from   t;
    
    COUNT(DISTINCTFEW_VALS)  COUNT(DISTINCTMANY_VALS)  COUNT(DISTINCTLOTS_VALS)  
    10                       1,000                     10,000     

    এগুলি শূন্যের সাথে প্যাডযুক্ত সংখ্যাগুলি numbers এটি পরে সংক্ষেপণের বিষয়ে বিন্দুটি তৈরি করতে সহায়তা করবে।

    সুতরাং আপনি তিনটি সাধারণ জিজ্ঞাসা পেয়েছেন:

    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  few_vals = '0000000001';
    
    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001';
    
    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001'
    and    few_vals = '0000000001';

    আপনি কি সূচক করবেন?

    পুরো টেবিল স্ক্যানের চেয়ে মাত্র কয়েকটি_ভালগুলিতে একটি সূচক কেবলমাত্র প্রান্তিকভাবে ভাল:

    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  few_vals = '0000000001';
    
    select * 
    from table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    -------------------------------------------------------------------------------------------  
    | Id  | Operation            | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  
    -------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT     |          |      1 |        |      1 |00:00:00.01 |      61 |  
    |   1 |  SORT AGGREGATE      |          |      1 |      1 |      1 |00:00:00.01 |      61 |  
    |   2 |   VIEW               | VW_DAG_0 |      1 |   1000 |   1000 |00:00:00.01 |      61 |  
    |   3 |    HASH GROUP BY     |          |      1 |   1000 |   1000 |00:00:00.01 |      61 |  
    |   4 |     TABLE ACCESS FULL| T        |      1 |   1000 |   1000 |00:00:00.01 |      61 |  
    -------------------------------------------------------------------------------------------
    
    select /*+ index (t (few_vals)) */
           count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  few_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    -------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  
    -------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |      58 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |      58 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |   1000 |   1000 |00:00:00.01 |      58 |  
    |   3 |    HASH GROUP BY                       |          |      1 |   1000 |   1000 |00:00:00.01 |      58 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |   1000 |   1000 |00:00:00.01 |      58 |  
    |   5 |      INDEX RANGE SCAN                  | FEW      |      1 |   1000 |   1000 |00:00:00.01 |       5 |  
    -------------------------------------------------------------------------------------------------------------

    সুতরাং এটি নিজের অনুসারে মূল্যবান হওয়ার সম্ভাবনা কম। প্রচুর_ভালোগুলিতে প্রশ্নগুলি কয়েকটি সারি ফেরত দেয় (এই ক্ষেত্রে 1 জন)। সুতরাং এটি অবশ্যই নির্ধারণের মূল্যবান।

    তবে উভয় কলামের বিরুদ্ধেই কি হবে?

    আপনার কি সূচক করা উচিত:

    ( few_vals, lots_vals )

    অথবা

    ( lots_vals, few_vals )

    কৌতুক প্রশ্ন!

    উত্তর না হয়।

    অবশ্যই কয়েকটি_ভাল দীর্ঘ স্ট্রিং। সুতরাং আপনি এটি থেকে ভাল সংক্ষেপণ পেতে পারেন। এবং আপনি (সম্ভবত) লট_ভালগুলিতে ভবিষ্যদ্বাণীযুক্ত (কয়েকটি_ভাল, প্রচুর_ভাল) ব্যবহার করে প্রশ্নের জন্য একটি সূচক স্কিপ স্ক্যান পান। তবে আমি এখানে নেই, যদিও এটি সম্পূর্ণ স্ক্যানের চেয়ে উল্লেখযোগ্যভাবে আরও ভাল পারফর্ম করে:

    create index few_lots on t(few_vals, lots_vals);
    
    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    -------------------------------------------------------------------------------------------  
    | Id  | Operation            | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  
    -------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT     |          |      1 |        |      1 |00:00:00.01 |      61 |  
    |   1 |  SORT AGGREGATE      |          |      1 |      1 |      1 |00:00:00.01 |      61 |  
    |   2 |   VIEW               | VW_DAG_0 |      1 |      1 |      1 |00:00:00.01 |      61 |  
    |   3 |    HASH GROUP BY     |          |      1 |      1 |      1 |00:00:00.01 |      61 |  
    |   4 |     TABLE ACCESS FULL| T        |      1 |      1 |      1 |00:00:00.01 |      61 |  
    -------------------------------------------------------------------------------------------  
    
    select /*+ index_ss (t few_lots) */count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    ----------------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  
    ----------------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |      13 |     11 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |      13 |     11 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |      1 |      1 |00:00:00.01 |      13 |     11 |  
    |   3 |    HASH GROUP BY                       |          |      1 |      1 |      1 |00:00:00.01 |      13 |     11 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |      1 |      1 |00:00:00.01 |      13 |     11 |  
    |   5 |      INDEX SKIP SCAN                   | FEW_LOTS |      1 |     40 |      1 |00:00:00.01 |      12 |     11 |  
    ----------------------------------------------------------------------------------------------------------------------

    আপনি কি জুয়া খেলা পছন্দ করেন? (2)

    সুতরাং আপনার এখনও অগ্রণী কলাম হিসাবে প্রচুর_ভালো সহ একটি সূচক প্রয়োজন। এবং কমপক্ষে এই ক্ষেত্রে যৌগিক সূচক (কয়েকটি, প্রচুর) ঠিক একই পরিমাণে কাজ করে (প্রচুর)

    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001'
    and    few_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    -------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  
    -------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |       3 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |       3 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |      1 |      1 |00:00:00.01 |       3 |  
    |   3 |    HASH GROUP BY                       |          |      1 |      1 |      1 |00:00:00.01 |       3 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |      1 |      1 |00:00:00.01 |       3 |  
    |   5 |      INDEX RANGE SCAN                  | FEW_LOTS |      1 |      1 |      1 |00:00:00.01 |       2 |  
    -------------------------------------------------------------------------------------------------------------  
    
    create index lots on t(lots_vals);
    
    select /*+ index (t (lots_vals)) */count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  lots_vals = '0000000001'
    and    few_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    ----------------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  
    ----------------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |       3 |      1 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |       3 |      1 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |      1 |      1 |00:00:00.01 |       3 |      1 |  
    |   3 |    HASH GROUP BY                       |          |      1 |      1 |      1 |00:00:00.01 |       3 |      1 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |      1 |      1 |00:00:00.01 |       3 |      1 |  
    |   5 |      INDEX RANGE SCAN                  | LOTS     |      1 |      1 |      1 |00:00:00.01 |       2 |      1 |  
    ----------------------------------------------------------------------------------------------------------------------  

    এমন কেস থাকবে যেখানে যৌগিক সূচক আপনাকে 1-2 আইও সংরক্ষণ করে। তবে এই সাশ্রয়ের জন্য দুটি সূচকের মূল্য কী?

    এবং সম্মিলিত সূচীতে আরও একটি সমস্যা আছে। LOTS_VALS সহ তিনটি সূচকের জন্য ক্লাস্টারিং ফ্যাক্টরের তুলনা করুন:

    create index lots on t(lots_vals);
    create index lots_few on t(lots_vals, few_vals);
    create index few_lots on t(few_vals, lots_vals);
    
    select index_name, leaf_blocks, distinct_keys, clustering_factor
    from   user_indexes
    where  table_name = 'T';
    
    INDEX_NAME  LEAF_BLOCKS  DISTINCT_KEYS  CLUSTERING_FACTOR  
    FEW_LOTS    47           10,000         530                
    LOTS_FEW    47           10,000         53                 
    LOTS        31           10,000         53                 
    FEW         31           10             530    

    লক্ষ্য করুন যে কয়েকটি_লটসের জন্য ক্লাস্টারিং ফ্যাক্টরটি 10x বেশি লট এবং লট_ফিউয়ের চেয়ে ! এবং এটি শুরু করার জন্য নিখুঁত ক্লাস্টারিং সহ একটি ডেমো টেবিলের মধ্যে রয়েছে। বাস্তব বিশ্বের ডাটাবেসে এর প্রভাব আরও খারাপ হতে পারে।

    তাহলে এতো খারাপ কী?

    ক্লাস্টারিং ফ্যাক্টর হ'ল সূচকটি কতটা "আকর্ষণীয়" তা নির্ধারণ করার অন্যতম মূল চালক। এটি যত বেশি, অপটিমাইজারটি এটি চয়ন করার সম্ভাবনা কম। বিশেষত যদি প্রচুর_ভালগুলি প্রকৃতপক্ষে অনন্য না হয় তবে তবুও সাধারণত মূল্য প্রতি কয়েকটি সারি থাকে। আপনি যদি দুর্ভাগ্য হন তবে এটি অপটিমাইজারকে মনে করতে পারে যে একটি সম্পূর্ণ স্ক্যান সস্তা is

    ঠিক আছে, সুতরাং কয়েকটি_ভাল এবং প্রচুর_ভাল সহ যৌগিক সূচকগুলিতে কেবল প্রান্তের ক্ষেত্রে সুবিধা রয়েছে।

    কয়েকটি_ভাল এবং বহু_ওয়ালগুলিকে ফিল্টারিং করা প্রশ্নাগুলি সম্পর্কে কী?

    একক কলাম সূচকগুলি কেবলমাত্র ছোট সুবিধা দেয়। তবে সম্মিলিত তারা কয়েকটি মান ফেরত দেয়। সুতরাং একটি যৌগিক সূচক একটি ভাল ধারণা। তবে কোন পথে?

    আপনি যদি প্রথম কয়েকটি স্থাপন করেন তবে শীর্ষস্থানীয় কলামটি সংকোচন করা আরও ছোট করে তুলবে

    create index few_many on t(many_vals, few_vals);
    create index many_few on t(few_vals, many_vals);
    
    select index_name, leaf_blocks, distinct_keys, clustering_factor 
    from   user_indexes
    where  index_name in ('FEW_MANY', 'MANY_FEW');
    
    INDEX_NAME  LEAF_BLOCKS  DISTINCT_KEYS  CLUSTERING_FACTOR  
    FEW_MANY    47           1,000          10,000             
    MANY_FEW    47           1,000          10,000   
    
    alter index few_many rebuild compress 1;
    alter index many_few rebuild compress 1;
    
    select index_name, leaf_blocks, distinct_keys, clustering_factor 
    from   user_indexes
    where  index_name in ('FEW_MANY', 'MANY_FEW');
    
    INDEX_NAME  LEAF_BLOCKS  DISTINCT_KEYS  CLUSTERING_FACTOR  
    MANY_FEW    31           1,000          10,000             
    FEW_MANY    34           1,000          10,000      

    নেতৃস্থানীয় কলামে কম ভিন্ন ভিন্ন মান সহ আরও ভাল সংক্ষেপে। সুতরাং এই সূচকটি পড়ার সামান্য কাজ রয়েছে। তবে কেবল সামান্য। এবং উভয়ই ইতিমধ্যে মূল (25% আকার হ্রাস) এর চেয়ে ছোট একটি ছোট অংশ।

    এবং আপনি আরও যেতে পারেন এবং পুরো সূচকটি সংকুচিত করতে পারেন!

    alter index few_many rebuild compress 2;
    alter index many_few rebuild compress 2;
    
    select index_name, leaf_blocks, distinct_keys, clustering_factor 
    from   user_indexes
    where  index_name in ('FEW_MANY', 'MANY_FEW');
    
    INDEX_NAME  LEAF_BLOCKS  DISTINCT_KEYS  CLUSTERING_FACTOR  
    FEW_MANY    20           1,000          10,000             
    MANY_FEW    20           1,000          10,000   

    এখন উভয় সূচক একই আকারে ফিরে এসেছে। নোট করুন এটি কয়েকটি এবং অনেকের মধ্যে একটি সম্পর্কের সত্যিকারের সুবিধা গ্রহণ করে। আবার এটি অসম্ভব যে আপনি আসল বিশ্বে এই ধরণের সুবিধা দেখতে পাবেন।

    এখনও পর্যন্ত আমরা কেবল সমতা পরীক্ষার বিষয়ে কথা বলেছি। প্রায়শই সম্মিলিত সূচীগুলির সাথে আপনার কোনও একটি কলামের মধ্যে বৈষম্য থাকবে। উদাহরণস্বরূপ "গত N দিনগুলিতে কোনও গ্রাহকের জন্য অর্ডার / শিপমেন্ট / চালানগুলি পান" এর মতো প্রশ্নগুলি।

    আপনার যদি এই ধরণের প্রশ্ন থাকে তবে আপনি সূচকের প্রথম কলামের বিপরীতে সমতা চান:

    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  few_vals < '0000000002'
    and    many_vals = '0000000001';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    -------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  
    -------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |      12 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |      12 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |     10 |     10 |00:00:00.01 |      12 |  
    |   3 |    HASH GROUP BY                       |          |      1 |     10 |     10 |00:00:00.01 |      12 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |     10 |     10 |00:00:00.01 |      12 |  
    |   5 |      INDEX RANGE SCAN                  | FEW_MANY |      1 |     10 |     10 |00:00:00.01 |       2 |  
    -------------------------------------------------------------------------------------------------------------  
    
    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )
    from   t
    where  few_vals = '0000000001'
    and    many_vals < '0000000002';
    
    select * 
    from   table(dbms_xplan.display_cursor(null, null, 'IOSTATS LAST -PREDICATE'));
    
    ----------------------------------------------------------------------------------------------------------------------  
    | Id  | Operation                              | Name     | Starts | E-Rows | A-Rows |   A-Time   | Buffers | Reads  |  
    ----------------------------------------------------------------------------------------------------------------------  
    |   0 | SELECT STATEMENT                       |          |      1 |        |      1 |00:00:00.01 |      12 |      1 |  
    |   1 |  SORT AGGREGATE                        |          |      1 |      1 |      1 |00:00:00.01 |      12 |      1 |  
    |   2 |   VIEW                                 | VW_DAG_0 |      1 |      2 |     10 |00:00:00.01 |      12 |      1 |  
    |   3 |    HASH GROUP BY                       |          |      1 |      2 |     10 |00:00:00.01 |      12 |      1 |  
    |   4 |     TABLE ACCESS BY INDEX ROWID BATCHED| T        |      1 |      2 |     10 |00:00:00.01 |      12 |      1 |  
    |   5 |      INDEX RANGE SCAN                  | MANY_FEW |      1 |      1 |     10 |00:00:00.01 |       2 |      1 |  
    ----------------------------------------------------------------------------------------------------------------------  

    লক্ষ্য করুন তারা বিপরীত সূচকটি ব্যবহার করছে।

    টি এল; ডিআর

    • সমতা শর্তযুক্ত কলামগুলি সূচকে প্রথম হওয়া উচিত।
    • যদি আপনার ক্যোয়ারিতে সাম্যগুলির সাথে একাধিক কলাম রয়েছে তবে প্রথমে কয়েকটিকে আলাদা আলাদা মান দিয়ে রাখলে সেরা সংকোচনের সুবিধা হবে
    • ইনডেক্স স্কিপ স্ক্যানগুলি সম্ভব হলেও আপনার আত্মবিশ্বাস থাকা দরকার এটি ভবিষ্যতের জন্য একটি কার্যকর বিকল্প হিসাবে থাকবে
    • নিকট-অনন্য কলাম সহ সংমিশ্র সূচকগুলি ন্যূনতম সুবিধা দেয়। আপনার অবশ্যই 1-2 আইওএস সংরক্ষণ করতে হবে তা নিশ্চিত হন

    1: কিছু ক্ষেত্রে এটি সূচীতে একটি কলাম অন্তর্ভুক্ত করা উচিত যদি এর অর্থ আপনার ক্যোয়ারীর সমস্ত কলামগুলি সূচীতে থাকে। এটি কেবলমাত্র একটি সূচি স্ক্যান সক্ষম করে, তাই আপনাকে টেবিলটি অ্যাক্সেস করার দরকার নেই।

    2: যদি আপনি ডায়াগনস্টিকস এবং টিউনিংয়ের জন্য লাইসেন্স পেয়ে থাকেন তবে আপনি এসকিউএল প্ল্যান ম্যানেজমেন্টের সাহায্যে পরিকল্পনাটি স্কিপ স্কিনে বাধ্য করতে পারেন

    ADDEDNDA

    পিএস - আপনি যে দস্তাবেজগুলি উদ্ধৃত করেছেন তা 9 আই থেকে রয়েছে। এটাই পুনরায় পুরানো। আমি আরও সাম্প্রতিক কিছু সঙ্গে থাকি


    select count (distinct few_vals || ':' || many_vals || ':' || lots_vals )সত্যিই সাধারণ একটি জিজ্ঞাসা ? ওরাকল সিনট্যাক্সের অনুমতি দেয় না select count (distinct few_vals, many_vals, lots_vals )- যা কোনও স্ট্রিং সংমিশ্রণ করে না, কলামগুলি পাঠ্য প্রকারের প্রয়োজন হয় না এবং :চরিত্রের অভাবে নির্ভর করে না ?
    ypercubeᵀᴹ

    @ ypercubeᵀᴹ আপনি count ( distinct x, y, z )ওরাকলে একটি করতে পারবেন না । সুতরাং আপনাকে একটি পৃথক সাবকোয়ারি করতে হবে এবং ফলাফলগুলি বা উপরের মতো একটি কনকেন্টেশন গণনা করতে হবে। আমি কেবল এখানে সারণির অ্যাক্সেসকে বাধ্য করার জন্য করেছি (কেবলমাত্র সূচক কেবল স্ক্যান না করে) এবং
    ক্রিস

    1

    সংকলনের সূচকটি কলামের বাছাইয়ের পাশাপাশি কোনও যৌগিক সূচকগুলি দিয়ে শুরু করা উচিত এবং / অথবা কী কী তা নিয়ে চূড়ান্ত সিদ্ধান্তে অবদান রাখে এমন প্রশ্নের আরও উপাদান রয়েছে।

    উদাহরণ স্বরূপ:

    1. কী ধরণের ক্যোয়ারী অপারেটর ব্যবহার করা হচ্ছে: যদি ক্যোয়ারিতে অপারেটর থাকে তবে
      ">,> =, <, <="
    2. ক্যোয়ারির ফলস্বরূপ কতগুলি আসল সারি প্রত্যাশিত: কোয়েরির ফলাফলটি সারণি থেকে সর্বাধিক সারি হতে চলেছে।
    3. যেখানে ক্লজ থাকাকালীন কোনও ফাংশন টেবিল কলামে ব্যবহৃত হচ্ছে: কোয়েরিতে যদি কোনও ফাংশন থাকে তবে কলামে যেখানে UPPER, LOWER, TRIM, SUBSTRING ব্যবহৃত হয় যেখানে শর্ত রয়েছে।

    এখনও কথোপকথন প্রাসঙ্গিক রাখতে আমার নীচের উত্তরটি নিম্নলিখিত পরিস্থিতিতে প্রযোজ্য:

    1. "প্রদত্ত টেবিলে 90% প্রকারের প্রশ্নের অপারেটরের সাথে যেখানে ক্লজ রয়েছে ="
    2. "সর্বাধিক ক্যোয়ারী ফলাফল হিসাবে টেবিলের মোট সারি 10% ফিরিয়ে দিচ্ছে"
    3. "যেখানে সারণীতে টেবিল কলামে কোনও ধরণের ফাংশন ব্যবহার করা হচ্ছে না"
    4. "যেখানে ক্লাউজের ব্যবহৃত বেশিরভাগ সময় কলামগুলি বেশিরভাগ ধরণের সংখ্যার,
      স্ট্রিংয়ের হয়"

    আমার অভিজ্ঞত্বে, এটি উভয়ই ডিবিএ সম্পর্কে সচেতন হওয়া উচিত।

    আসুন কল্পনা করুন যে কেবলমাত্র একটি নিয়ম প্রয়োগ হচ্ছে:

    1) যদি আমি বেশিরভাগ নির্বাচনী কলামের সাথে সূচক তৈরি করি তবে সেই কলামটি ডিবি ইঞ্জিনের জন্য কোনও ব্যবহারের চেয়ে সেই টেবিলের বেশিরভাগ প্রশ্নের দ্বারা বাস্তবে ব্যবহৃত হয় না।

    ২) যদি আমি সূচীতে প্রথম অবস্থানে থাকা কোন প্রশ্নের মধ্যে সর্বাধিক ব্যবহৃত কলামের সাথে একটি সূচক তৈরি করি তবে কলামের মধ্যেও কম নির্বাচন রয়েছে তবে আমার ক্যোয়ারী পারফরম্যান্সটি ভাল হবে না।

    আমি বেশিরভাগ টেবিল প্রশ্নের 90% ব্যবহার করা কলামগুলি তালিকাবদ্ধ করব। তারপরে এগুলি কেবলমাত্র বেশিরভাগ কার্ডিনালিটির সাথে অন্তত কার্ডিনালিটির ক্রমে রাখুন put

    আমরা পাঠ্য ক্যোয়ারি পারফরম্যান্সের উন্নতির জন্য সূচকগুলি ব্যবহার করি এবং সেই কর্মপ্রবাহ (একটি পাঠের ক্যোয়ারির প্রকারগুলি) কেবলমাত্র সূচি তৈরির গাড়ি চালায়। প্রকৃতপক্ষে ডেটা বাড়ার সাথে সাথে (কোটি কোটি সারি) সংকুচিত সূচক স্টোরেজ বাঁচাতে পারে তবে অবশ্যই পড়ার ক্যোয়ারী কর্মক্ষমতা ক্ষতিগ্রস্থ করবে।


    1

    তত্ত্বের মধ্যে সবচেয়ে নির্বাচনী কলাম দ্রুততম অনুসন্ধান দেয়। তবে কর্মক্ষেত্রে আমি কেবল এমন পরিস্থিতিতে গিয়ে হোঁচট খেয়েছি যেখানে আমাদের কাছে সবচেয়ে বেছে বেছে প্রথম অংশের 3 অংশের সংমিশ্রিত সূচক রয়েছে। (তারিখ, লেখক, প্রকাশনা সংস্থা বলতে দেয় যে সেই ক্রমে, সারণী পোস্টগুলিতে থাম্ব আপ রাখে) এবং আমার কাছে একটি কোয়েরি রয়েছে যা সমস্ত 3 অংশ ব্যবহার করে। মাইএসকিএল আমার প্রশ্নের সাথে উপস্থিত থাকা সত্ত্বেও সংস্থাগুলি এবং তারিখ সমন্বিত সংমিশ্রিত সূচকটি এড়িয়ে লেখক অনলিকে সূচক ব্যবহার করে ডিফল্ট হয়েছে। আমি যৌগিক ব্যবহারের জন্য ফোর্স সূচক ব্যবহার করেছি এবং ক্যোয়ারীটি আসলে ধীর গতিতে চলেছে। কেন এমন হল? আমি আপনাকে বলব:

    আমি তারিখে একটি ব্যাপ্তি নির্বাচন করছিলাম, সুতরাং তারিখটি অত্যন্ত নির্বাচনী হওয়া সত্ত্বেও, আমরা এটিকে ব্যাপ্তি স্ক্যানগুলির জন্য ব্যবহার করছি (যদিও পরিসীমা তুলনামূলকভাবে ছোট, 6 বছরের ডেটার মধ্যে 6 মাস) যৌগিককে ক্ষতিকারক করে তুলেছে MySQL। এই বিশেষ ক্ষেত্রে সংমিশ্রণটি ব্যবহার করার জন্য, মাইএসকিএলকে নতুন বছর থেকে রচিত সমস্ত নিবন্ধগুলি ধরে ফেলতে হবে তবে লেখক কে সে সম্পর্কে ডুব দিয়েছিলেন এবং এই লেখক যে লেখক লিখেছেন নি যে অন্যান্য লেখকদের তুলনায় অনেক নিবন্ধ রয়েছে, মাইএসকিএল কেবল সেই লেখককেই খুঁজে পেতে পছন্দ করেছেন ।

    অন্য ক্ষেত্রে ক্যোয়ারীটি সংমিশ্রণে অনেক দ্রুত ছড়িয়েছিল, কেসটি যখন লেখক বিপুল পরিমাণে জনপ্রিয় ছিলেন এবং বেশিরভাগ রেকর্ডের মালিক ছিলেন, তারিখ অনুসারে বাছাই করে তা বোঝানো হত। তবে মাইএসকিএল সেই মামলাটি স্বয়ংক্রিয়ভাবে সনাক্ত করতে পারেনি, আমাকে জোর করে সূচী করতে হয়েছিল ... তাই আপনি জানেন যে এটির পরিবর্তিত হয়। ব্যাপ্তি স্ক্যানগুলি আপনার নির্বাচিত কলামটি অকেজো করে দিতে পারে। ডেটা বিতরণ এমন ক্ষেত্রে তৈরি করতে পারে যেখানে কলামগুলি বিভিন্ন রেকর্ডের জন্য আরও নির্বাচনী ...

    আমি আলাদাভাবে যা করব তা হ'ল তারিখটি (যা আবার তাত্ত্বিকভাবে সর্বাধিক নির্বাচনী) ডানে স্থানান্তর করা, যেহেতু আমি জানি যে আমি এখন এটিতে একটি রেঞ্জ স্ক্যান করবো এবং এটি একটি তাত্পর্য তৈরি করে।


    1
    যদি আপনার ক্যোয়ারীর মতো কিছু থাকে WHERE (date BETWEEN @x AND @y) AND (author = @a) AND (publishing company = @p)তবে তার উপর একটি সূচি চালু (author, publishing_company, date)বা চালু (publishing_company, author, date)রাখা ভাল cing
    ypercubeᵀᴹ

    -2

    বিভিন্ন পরিস্থিতিতে বিভিন্ন ক্ষেত্রে। আপনার লক্ষ্য জানুন; তারপরে আপনার সূচী তৈরি করুন এবং প্রত্যেকের জন্য পরিকল্পনা ব্যাখ্যা করুন এবং আপনার পরিস্থিতির জন্য আপনার সেরা উত্তর থাকবে।


    -2

    জিজ্ঞাসা টমের সূচকে কলাম ক্রম থেকে :

    সুতরাং, আপনার সূচীতে কলামগুলির ক্রম নির্ভর করে আপনার প্রশ্নগুলি কীভাবে লেখা হয়। আপনি যতটা ক্যোয়ারির জন্য সূচকটি ব্যবহার করতে সক্ষম হতে চান (যাতে আপনার যতগুলি সংখ্যক সূচকে ছাড়িয়ে যায়) - এটি কলামগুলির ক্রমকে চালিত করবে। আর কিছুই নয় (a বা b এর সিলেক্টিভিটি মোটেই গণ্য হয় না)।

    সম্মত হন, আমাদের কোথায় ধারাটির ভিত্তিতে কলামগুলি অর্ডার করতে হবে, তবে "(a বা b এর নির্বাচনীতা মোটেও গণনা করা হয় না") "সঠিক নয়।" "। সর্বাধিক নির্বাচিত কলামগুলি যদি এটি প্রথম ভূমিকা সন্তুষ্ট হয় তবে নেতৃত্ব দেওয়া উচিত ("যেখানে ধারা")

    আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
    Licensed under cc by-sa 3.0 with attribution required.