DB btree/hash performance

I tested performance of some in-memory BDB containers with DB_BTREE/DB_HASH access. Performance of C++ std::map-based containers (with the simplest synchronization using a critical section) are ~ 30-40% higher as compared with these in-memory databases. The tests are done on a 1-CPU Windows XP computer running 1 writer and 4 readers. I used CDB Berkeley subsystem.
Is there any way to make BDB faster? Even if I run 4 readers only (and do not run a writer), the performance will not be much higher (~15%-20).
Thank you

Hi Michael,
Are you comparing the performance of Berkeley DB with some STL implementation?Surely, comparing the performance of BDB with standard C++ containers might be useless, if someone tried to answer the questions: “what is faster?“, or “is it possible to make BDB as fast as STL containers?“. Obviously, the answer would be: BDB and STL are for different purposes; so there is no sense to compare them. But behavior of the standard containers (along with simplest synchronization routines) is very well known; and comparison of BDB with a standard container on a particular PC could give not a bad relative estimation of the BDB performance. Such a relative estimation may be better than something like “performance is 10000 requests per second”, because the test results will be different on different PCs, with different CPUs, with different … many things. Maybe I am wrong. Please, correct me if so.
If so, is there some reason that you can't just use STL?I told about in-memory BDB just in order to show that performance of the tested BDBs did not relate to disk IO. But in fact, I need non-in-memory BDB in my application. The data must be on a disk. That is why I cannot just use STL. In fact, data will come to some STL containers first, and then data will be queued in order to update a BDB storage (non in-memory). When the application restarts, the data will be re-loaded from the persistent BDB storage.
What operations does your workload perform? What are your concurrency
requirements and performance goals? The application has a BDB storage (DB_BTREE/DB_HASH) with some 5000 keys. After the application has loaded this “map” at startup, only one “writer” thread may very rarely add/delete entries from the “map”. The impact of this process on the performance should be close to 0.
The same “writer” thread intensively updates values of the map (for given keys). The writer thread may issue ~ 1-10 updates per ms. The biggest problem is that the number of updates may be much higher in case of data spikes (up to 30 updates per ms and higher).
Also, the application has 4-5 “reader” threads, which relatively rarely (once per 100-500 ms) access the “map” reading the values “by key“.
The BDB write/read access should have “write favor” - readers may perform “uncommitted” reading, preferably not blocking the “writer“ thread.
Can you give some absolute numbers for the results you are seeing rather than >>percentages? Here is a typical output of the test application running on a 1-CPU Windows XP PC:
STL: std::map-based container (critical section synchronization):
== consumer statistics ==
consumer (0), duration sec.(0.454418), iterations done(1000000)
consumer (1), duration sec.(0.494315), iterations done(1000000)
consumer (2), duration sec.(0.343084), iterations done(1000000)
consumer (3), duration sec.(0.109292), iterations done(1000000)
== producer statistics ==
producer (0), duration sec.(0.297399), iterations done(1000000)
BDB:
== consumer statistics ==
consumer (0), duration sec.(24.055119), iterations done(1000000)
consumer (1), duration sec.(27.551431), iterations done(1000000)
consumer (2), duration sec.(28.282188), iterations done(1000000)
consumer (3), duration sec.(27.537262), iterations done(1000000)
== producer statistics ==
producer (0), duration sec.(30.986818), iterations done(1000000)
Thank you

Similar Messages

  • Can multiple threads write to the database?

    I am a little confused from the statement in the documentation: "Berkeley DB Data Store does not support locking, and hence does not guarantee correct behavior if more than one thread of control is updating the database at a time."
    1. Can multiple threads write to the "Simple Data Store"?
    2. Considering the sample code below which writes to the DB using 5 threads - is there a possibility of data loss?
    3. If the code will cause data loss, will adding DB_INIT_LOCK and/or DB_INIT_TXN in DBENV->open make any difference?
    #include "stdafx.h"
    #include <stdio.h>
    #include <windows.h>
    #include <db.h>
    static DB *db = NULL;
    static DB_ENV *dbEnv = NULL;
    DWORD WINAPI th_write(LPVOID lpParam)
    DBT key, data;
    char key_buff[32], data_buff[32];
    DWORD i;
    printf("thread(%s) - start\n", lpParam);
    for (i = 0; i < 200; ++i)
    memset(&key, 0, sizeof(key));
    memset(&data, 0, sizeof(data));
    sprintf(key_buff, "K:%s", lpParam);
    sprintf(data_buff, "D:%s:%8d", lpParam, i);
    key.data = key_buff;
    key.size = strlen(key_buff);
    data.data = data_buff;
    data.size = strlen(data_buff);
    db->put(db, NULL, &key, &data, 0);
    Sleep(5);
    printf("thread(%s) - End\n", lpParam);
    return 0;
    int main()
    db_env_create(&dbEnv, 0);
    dbEnv->open(dbEnv, NULL, DB_CREATE | DB_INIT_MPOOL | DB_THREAD, 0);
    db_create(&db, dbEnv, 0);
    db->open(db, NULL, "test.db", NULL, DB_BTREE, DB_CREATE, 0);
    CreateThread(NULL, 0, th_write, "A", 0, 0);
    CreateThread(NULL, 0, th_write, "B", 0, 0);
    CreateThread(NULL, 0, th_write, "B", 0, 0);
    CreateThread(NULL, 0, th_write, "C", 0, 0);
    th_write("C");
    Sleep(2000);
    }

    Here some clarification about BDB Lock and Multi threads behavior
    Question 1. Can multiple threads write to the "Simple Data Store"?
    Answer 1.
    Please Refer to http://docs.oracle.com/cd/E17076_02/html/programmer_reference/intro_products.html
    A Data Store (DS) set up
    (so not using an environment or using one, but without any of the DB_INIT_LOCK, DB_INIT_TXN, DB_INIT_LOG environment regions related flags specified
    each corresponding to the appropriate subsystem, locking, transaction, logging)
    will not guard against data corruption due to accessing the same database page and overwriting the same records, corrupting the internal structure of the database etc.
    (note that in the case of the Btree, Hash and Recno access methods we lock at the database page level, only for the Queue access method we lock at record level)
    So,
    if You want to have multiple threads in the application writing concurrently or in parallel to the same database You need to use locking (and properly handle any potential deadlocks),
    otherwise You risk corrupting the data itself or the database (its internal structure).
    Of course , If You serialize at the application level the access to the database, so that no more one threads writes to the database at a time, there will be no need for locking.
    But obviously this is likely not the behavior You want.
    Hence, You need to use either a CDS (Concurrent Data Store) or TDS (Transactional Data Store) set up.
    See the table comparing the various set ups, here: http://docs.oracle.com/cd/E17076_02/html/programmer_reference/intro_products.html
    Berkeley DB Data Store
    The Berkeley DB Data Store product is an embeddable, high-performance data store. This product supports multiple concurrent threads of control, including multiple processes and multiple threads of control within a process. However, Berkeley DB Data Store does not support locking, and hence does not guarantee correct behavior if more than one thread of control is updating the database at a time. The Berkeley DB Data Store is intended for use in read-only applications or applications which can guarantee no more than one thread of control updates the database at a time.
    Berkeley DB Concurrent Data Store
    The Berkeley DB Concurrent Data Store product adds multiple-reader, single writer capabilities to the Berkeley DB Data Store product. This product provides built-in concurrency and locking feature. Berkeley DB Concurrent Data Store is intended for applications that need support for concurrent updates to a database that is largely used for reading.
    Berkeley DB Transactional Data Store
    The Berkeley DB Transactional Data Store product adds support for transactions and database recovery. Berkeley DB Transactional Data Store is intended for applications that require industrial-strength database services, including excellent performance under high-concurrency workloads of read and write operations, the ability to commit or roll back multiple changes to the database at a single instant, and the guarantee that in the event of a catastrophic system or hardware failure, all committed database changes are preserved.
    So, clearly DS is not a solution for this case, where multiple threads need to write simultaneously to the database.
    CDS (Concurrent Data Store) provides locking features, but only for multiple-reader/single-writer scenarios. You use CDS when you specify the DB_INIT_CDB flag when opening the BDB environment: http://docs.oracle.com/cd/E17076_02/html/api_reference/C/envopen.html#envopen_DB_INIT_CDB
    TDS (Transactional Data Store) provides locking features, adds complete ACID support for transactions and offers recoverability guarantees. You use TDS when you specify the DB_INIT_TXN and DB_INIT_LOG flags when opening the environment. To have locking support, you would need to also specify the DB_INIT_LOCK flag.
    Now, since the requirement is to have multiple writers (multi-threaded writes to the database),
    then TDS would be the way to go (CDS is useful only in single-writer scenarios, when there are no needs for recoverability).
    To Summarize
    The best way to have an understanding of what set up is needed, it is to answer the following questions:
    - What is the data access scenario? Is it multiple writer threads? Will the writers access the database simultaneously?
    - Are recoverability/data durability, atomicity of operations and data isolation important for the application? http://docs.oracle.com/cd/E17076_02/html/programmer_reference/transapp_why.html
    If the answers are yes, then TDS should be used, and the environment should be opened like this:
    dbEnv->open(dbEnv, ENV_HOME, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG | DB_RECOVER | DB_THREAD, 0);
    (where ENV_HOME is the filesystem directory where the BDB environment will be created)
    Question 2. Considering the sample code below which writes to the DB using 5 threads - is there a possibility of data loss?
    Answer 2.
    Definitely yes, You can see data loss and/or data corruption.
    You can check the behavior of your testcase in the following way
    1. Run your testcase
    2.After the program exits
    run db_verify to verify the database (db_verify -o test.db).
    You will likely see db_verify complaining, unless the thread scheduler on Windows weirdly starts each thread one after the other,
    IOW no two or ore threads write to the database at the same time -- kind of serializing the writes
    Question 3. If the code will cause data loss, will adding DB_INIT_LOCK and/or DB_INIT_TXN in DBENV->open make any difference?
    Answer 3.
    In Your case the TDS should be used, and the environment should be opened like this:
    dbEnv->open(dbEnv, ENV_HOME, DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_TXN | DB_INIT_LOG | DB_RECOVER | DB_THREAD, 0);
    (where ENV_HOME is the filesystem directory where the BDB environment will be created)
    doing this You have proper deadlock handling in place and proper transaction usage
    so
    You are protected against potential data corruption/data loss.
    see http://docs.oracle.com/cd/E17076_02/html/gsg_txn/C/BerkeleyDB-Core-C-Txn.pdf
    Multi-threaded and Multi-process Applications
    DB is designed to support multi-threaded and multi-process applications, but their usage
    means you must pay careful attention to issues of concurrency. Transactions help your
    application's concurrency by providing various levels of isolation for your threads of control. In
    addition, DB provides mechanisms that allow you to detect and respond to deadlocks.
    Isolation means that database modifications made by one transaction will not normally be
    seen by readers from another transaction until the first commits its changes. Different threads
    use different transaction handles, so this mechanism is normally used to provide isolation
    between database operations performed by different threads.
    Note that DB supports different isolation levels. For example, you can configure your
    application to see uncommitted reads, which means that one transaction can see data that
    has been modified but not yet committed by another transaction. Doing this might mean
    your transaction reads data "dirtied" by another transaction, but which subsequently might
    change before that other transaction commits its changes. On the other hand, lowering your
    isolation requirements means that your application can experience improved throughput due
    to reduced lock contention.
    For more information on concurrency, on managing isolation levels, and on deadlock
    detection, see Concurrency (page 32).

  • How recover data from .dat file without application

    Dears,
    We are active for a few customers who will use an windows application with, so far we can see, an flat file UNIX structure database. It seems that the structure of the database is nearly the structure who used in Berkeley DB. That means that we have analysed the database and found 'information blocks' like Btree, hash tables etc.
    Is their any way to start reverse engineering on the single .dat file, if we have no idea what fields or record the application uses.
    It is hard to believe but the software firm did not want to make the data free .. only for a lot of money .. so far we know the customer is the owner of the data, and the firm have to do that!
    But we can't wait to get the data out this file ... we need some little more help.. to analyse the database and its block structure .. so when we know the database structure (the blocks) we can start analysing the data.
    Many thanks,
    for any reply
    Eric

    Hi Eric,
    We've rarely seen applications using BDB use that extension for the database (it's of course possible to name the file any way you want, but generally the BDB database files use .db as the extension). So, I have a feeling you're facing a file created with another database engine. Nevertheless, here is what you can do:
    - determine the file's size on the disk and post it here;
    - run the following BDB utilities on the .dat file (we'll call it "file.dat")
    db_verify file.dat
    db_stat -d file.datand post here the output.
    You can download Berkeley DB here:
    http://www.oracle.com/technology/software/products/berkeley-db/db/index.html
    For information on how to build on Windows:
    http://www.oracle.com/technology/documentation/berkeley-db/db/ref/build_win/intro.html
    Detailed description of the utilities I've mentioned:
    http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_verify.html
    http://www.oracle.com/technology/documentation/berkeley-db/db/utility/db_stat.html
    Also, I would like to suggest you the following.
    Since the data within the file is probably confidential, I can take this issue in private and open a Metalink SR for you. I can assure you that we will treat all information as confidential.
    If you would like me to help this way, just send me an email at: andrei dot costache at oracle dot com.
    Regards,
    Andrei

  • How to reduce the size of file after delete some datas?

    The size of the database file isn't smaller than ago after delete some data from database.
    How to reduce the size of file after delete some datas?

    Hi,
    What BDB release are you using? If it's one of the latest releases, then what you are looking for is the DB->compact() method:
    http://download.oracle.com/docs/cd/E17076_01/html/api_reference/C/dbcompact.html
    The DB->compact() method compacts Btree, Hash, and Recno access method databases, and optionally returns unused Btree, Hash or Recno database pages to the underlying filesystem. Please let me know if it helps.
    Bogdan Coman

  • Read performance of a generically typed hashed table

    Hi,
        I'm curious to know the how the read performance of a hashed table will be affected in the following scenario. I have a class with many static attributes of hashed table type. All these hashed tables have one thing in common. They have a field "GUID" as unique key. The processing logic is same for all tables and hence I made the code generic. For example, I have an importing parameter with which I can "derive" the name of my class attribute.
    field-symbols: <fs_table> type hashed table,
                           <fs_line> type any.
    lv_class_attr = derive_name( iv_object_name ).
    assign (lv_class_Attr) to <fs_table>.
    read table <fs_table> with table key ('GUID') assigning <fs_line>.
    Will this code block give me the same performance that I would get if I use specifically typed hash tables? The code inspector gives me a low performance warning. But what will actually happen at runtime?
    Regards,
    Arun Prakash

    Hi,
    It is very simple. You defined table without unique key that why?.
    Whenever we define the typed hased table it require the unique key required. In your case it is dynamic hased table. It's don't have any unique key, While build internal hased table it require unique key defination. by in case of non-type table don't know the unique key fields.
    While reading data it will work like the standard table due to non unique key defination and It used the sequention read.

  • Performance Tuning - remove hash join

    Hi Every one,
    Can some one help in tuning below query, i have hash join taking around 84%, 
    SELECT
    PlanId
    ,ReplacementPlanId
    FROM
    ( SELECT
    pl.PlanId
    ,xpl.PlanId ReplacementPlanId
    ,ROW_NUMBER() OVER(PARTITION BY pl.PlanId ORDER BY xpl.PlanId) RN
    FROM [dbo].[Plan] pl
    JOIN [dbo].[Plan] xpl
    ON pl.PPlanId = xpl.PPlanId
    AND pl.Name = xpl.Name
    WHERE
    pl.SDate > (CONVERT(CHAR(10),DATEADD(M,-12,GETDATE()),120)) AND
    xpl.Live = 1
    AND pl.TypeId = 7
    AND xpl.TypeId = 7
    ) p
    WHERE RN = 1
    Thanks in advance

    Can you show an execution plan of the query? Is that possible to rewrite the query as 
    Sorry cannot test it right now
    SELECT
    PlanId
    ,ReplacementPlanId
    FROM
    (SELECT PlanId,Name,SDate,TypeId FROM [dbo].[Plan]) pl
    CROSS APPLY 
     SELECT TOP (1) TypeId ,Live FROM [Plan] xpl
     WHERE  pl.PPlanId = xpl.PPlanId
    AND pl.Name = xpl.Name
    ) AS Der
    WHERE pl.SDate > (CONVERT(CHAR(10),DATEADD(M,-12,GETDATE()),120)) AND  
    Der.Live = 1
    AND pl.TypeId = 7
    AND Der.TypeId = 7
    Best Regards,Uri Dimant SQL Server MVP,
    http://sqlblog.com/blogs/uri_dimant/
    MS SQL optimization: MS SQL Development and Optimization
    MS SQL Consulting:
    Large scale of database and data cleansing
    Remote DBA Services:
    Improves MS SQL Database Performance
    SQL Server Integration Services:
    Business Intelligence

  • Performance- Hash Joins ?

    Hi everyone,
    Version :- 10.1.0.5.0
    Below is the query and it takes long time to execute due to hash joins. Is there ant other way to change change the join approach or rewrite the SQL.
    Tables used
    rhs_premium :- 830 GB with partitons.
    bu_res_line_map :- small table 4 MB
    mgt_unit_res_line_map :- small table with 4 MB
    mgt_unit_reserving_lines :- View
    bu_reserving_lines :- View
    SELECT  prem.business_unit,
            prem.direct_assumed_ceded_code,
            prem.ledger_currency_code,
            prem.mcc_code,
            prem.management_unit,
            prem.product,
            prem.financial_product,
            nvl(prem.premium_in_ledger_currency,0) premium_in_ledger_currency,      -- NVL added Aug 21, 2008
            nvl(prem.premium_in_original_currency,0) premium_in_original_currency,  -- Added Aug 21, 2008  M4640
            nvl(prem.premium_in_us_dollars,0) premium_in_us_dollars,                -- NVL added Aug 21, 2008
            prem.rcc,
            prem.pre_explosion_rcc,                               -- Issue M1997 Laks 09/15
            prem.acc_code,
            prem.transaction_code,
            prem.accounting_period,
            prem.exposure_period,
            prem.policy_effective_month,
            prem.policy_key,
            prem.policy_line_of_business,
            prem.producer_code,
            prem.underwriting_year,
            prem.ledger_key,
            prem.account_key,
            prem.policy_coverage_key,
            nvl(prem.original_currency_code,' ') original_currency_code,   -- NVL added Issue M4640  Aug 21, 2008
            prem.authorized_unauthorized,
            prem.transaction_effective_date,
            prem.transaction_expiration_date,
            prem.exposure_year,
            prem.reinsurance_mask,
            prem.rcccategory,
            prem.rccclassification,
            prem.detail_level_indicator,
            prem.bermbase_level_indicator,
            prem.padb_level_indicator,
            prem.sas_level_indicator,                             -- Issue 443
            prem.cnv_adjust_indicator,                            -- Issue 413
            prem.originating_business_unit,
            prem.actuarial_blend_indicator,
            ml1.management_line_of_business_id management_lob_id_act,
            mu1.reserving_line_id mgt_unit_reserving_lob_id_act,
            bu1.reserving_line_id business_unit_lob_id_act,
            ml1.reserving_class_id mgt_unit_res_class_lob_id_act, -- added A12
            bl1.reserving_class_id business_unit_class_lob_id_act,-- added A12
            ml2.management_line_of_business_id management_lob_id_fin,
            mu2.reserving_line_id mgt_unit_reserving_lob_id_fin,
            bu2.reserving_line_id business_unit_lob_id_fin,
            ml2.reserving_class_id mgt_unit_res_class_lob_id_fin, -- added A12
            bl2.reserving_class_id business_unit_class_lob_id_fin -- added A12
      FROM rhs_premium prem,
            bu_res_line_map bu1,
            mgt_unit_res_line_map mu1,
            mgt_unit_reserving_lines ml1,
            bu_reserving_lines bl1,                               -- added A12
            bu_res_line_map bu2,
            mgt_unit_res_line_map mu2,
            mgt_unit_reserving_lines ml2,
            bu_reserving_lines bl2                                -- added A12
       WHERE  (      prem.business_unit = bu1.business_unit (+)
              AND  prem.product = bu1.product (+)
       AND  (      prem.management_unit = mu1.management_unit (+)
              AND  prem.product = mu1.product(+)
       AND  mu1.reserving_line_id = ml1.reserving_line_id (+)
       AND  bu1.reserving_line_id = bl1.reserving_line_id (+)    -- added A12
       AND  (      prem.business_unit = bu2.business_unit (+)
              AND  prem.financial_product = bu2.product (+)
       AND  (      prem.management_unit = mu2.management_unit (+)
              AND  prem.financial_product = mu2.product(+)
       AND  mu2.reserving_line_id = ml2.reserving_line_id (+)
       AND  bu2.reserving_line_id = bl2.reserving_line_id (+);
    PLAN_TABLE_OUTPUT
    Plan hash value: 3475794837
    | Id  | Operation                         | Name                     | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |    TQ  |IN-OUT| PQ Distrib |
    |   0 | SELECT STATEMENT                  |                          |   346M|   124G|   416K  (2)| 01:37:13 |       |       |        |      |            |
    |   1 |  PX COORDINATOR                   |                          |       |       |            |          |       |       |        |      |            |
    |   2 |   PX SEND QC (RANDOM)             | :TQ10008                 |   346M|   124G|   416K  (2)| 01:37:13 |       |       |  Q1,08 | P->S | QC (RAND)  |
    |*  3 |    HASH JOIN RIGHT OUTER          |                          |   346M|   124G|   416K  (2)| 01:37:13 |       |       |  Q1,08 | PCWP |            |
    |   4 |     BUFFER SORT                   |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |   5 |      PX RECEIVE                   |                          |    46 |  1196 |     7   (0)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |   6 |       PX SEND BROADCAST           | :TQ10000                 |    46 |  1196 |     7   (0)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |   7 |        VIEW                       | BU_RESERVING_LINES       |    46 |  1196 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |   8 |         NESTED LOOPS OUTER        |                          |    46 |  1748 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |*  9 |          TABLE ACCESS FULL        | RESERVING_LINES          |    46 |  1564 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |* 10 |          INDEX UNIQUE SCAN        | RESERVING_CLASSES_PK     |     1 |     4 |     0   (0)| 00:00:01 |       |       |        |      |            |
    |* 11 |     HASH JOIN RIGHT OUTER         |                          |   346M|   116G|   415K  (2)| 01:37:04 |       |       |  Q1,08 | PCWP |            |
    |  12 |      BUFFER SORT                  |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  13 |       PX RECEIVE                  |                          |   124K|  2182K|    87   (2)| 00:00:02 |       |       |  Q1,08 | PCWP |            |
    |  14 |        PX SEND BROADCAST          | :TQ10001                 |   124K|  2182K|    87   (2)| 00:00:02 |       |       |        | S->P | BROADCAST  |
    |  15 |         TABLE ACCESS FULL         | BU_RES_LINE_MAP          |   124K|  2182K|    87   (2)| 00:00:02 |       |       |        |      |            |
    |* 16 |      HASH JOIN RIGHT OUTER        |                          |   346M|   110G|   415K  (2)| 01:36:54 |       |       |  Q1,08 | PCWP |            |
    |  17 |       BUFFER SORT                 |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  18 |        PX RECEIVE                 |                          |    46 |  1196 |     7   (0)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |  19 |         PX SEND BROADCAST         | :TQ10002                 |    46 |  1196 |     7   (0)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |  20 |          VIEW                     | BU_RESERVING_LINES       |    46 |  1196 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |  21 |           NESTED LOOPS OUTER      |                          |    46 |  1748 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |* 22 |            TABLE ACCESS FULL      | RESERVING_LINES          |    46 |  1564 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |* 23 |            INDEX UNIQUE SCAN      | RESERVING_CLASSES_PK     |     1 |     4 |     0   (0)| 00:00:01 |       |       |        |      |            |
    |* 24 |       HASH JOIN RIGHT OUTER       |                          |   346M|   101G|   414K  (1)| 01:36:45 |       |       |  Q1,08 | PCWP |            |
    |  25 |        BUFFER SORT                |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  26 |         PX RECEIVE                |                          |   124K|  2182K|    87   (2)| 00:00:02 |       |       |  Q1,08 | PCWP |            |
    |  27 |          PX SEND BROADCAST        | :TQ10003                 |   124K|  2182K|    87   (2)| 00:00:02 |       |       |        | S->P | BROADCAST  |
    |  28 |           TABLE ACCESS FULL       | BU_RES_LINE_MAP          |   124K|  2182K|    87   (2)| 00:00:02 |       |       |        |      |            |
    |* 29 |        HASH JOIN RIGHT OUTER      |                          |   346M|    96G|   413K  (1)| 01:36:35 |       |       |  Q1,08 | PCWP |            |
    |  30 |         BUFFER SORT               |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  31 |          PX RECEIVE               |                          |    46 |  1794 |    11  (10)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |  32 |           PX SEND BROADCAST       | :TQ10004                 |    46 |  1794 |    11  (10)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |  33 |            VIEW                   | MGT_UNIT_RESERVING_LINES |    46 |  1794 |    11  (10)| 00:00:01 |       |       |        |      |            |
    |* 34 |             HASH JOIN OUTER       |                          |    46 |  1886 |    11  (10)| 00:00:01 |       |       |        |      |            |
    |* 35 |              TABLE ACCESS FULL    | RESERVING_LINES          |    46 |  1564 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |  36 |              TABLE ACCESS FULL    | RESERVING_CLASSES        |   107 |   749 |     3   (0)| 00:00:01 |       |       |        |      |            |
    |* 37 |         HASH JOIN RIGHT OUTER     |                          |   346M|    83G|   413K  (1)| 01:36:26 |       |       |  Q1,08 | PCWP |            |
    |  38 |          BUFFER SORT              |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  39 |           PX RECEIVE              |                          | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |  40 |            PX SEND BROADCAST      | :TQ10005                 | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |  41 |             INDEX FAST FULL SCAN  | MGT_UNIT_RES_LINE_MAP_UK | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |        |      |            |
    |* 42 |          HASH JOIN RIGHT OUTER    |                          |   346M|    77G|   412K  (1)| 01:36:17 |       |       |  Q1,08 | PCWP |            |
    |  43 |           BUFFER SORT             |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  44 |            PX RECEIVE             |                          |    46 |  1794 |    11  (10)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |  45 |             PX SEND BROADCAST     | :TQ10006                 |    46 |  1794 |    11  (10)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |  46 |              VIEW                 | MGT_UNIT_RESERVING_LINES |    46 |  1794 |    11  (10)| 00:00:01 |       |       |        |      |            |
    |* 47 |               HASH JOIN OUTER     |                          |    46 |  1886 |    11  (10)| 00:00:01 |       |       |        |      |            |
    |* 48 |                TABLE ACCESS FULL  | RESERVING_LINES          |    46 |  1564 |     7   (0)| 00:00:01 |       |       |        |      |            |
    |  49 |                TABLE ACCESS FULL  | RESERVING_CLASSES        |   107 |   749 |     3   (0)| 00:00:01 |       |       |        |      |            |
    |* 50 |           HASH JOIN RIGHT OUTER   |                          |   346M|    65G|   411K  (1)| 01:36:08 |       |       |  Q1,08 | PCWP |            |
    |  51 |            BUFFER SORT            |                          |       |       |            |          |       |       |  Q1,08 | PCWC |            |
    |  52 |             PX RECEIVE            |                          | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |  Q1,08 | PCWP |            |
    |  53 |              PX SEND BROADCAST    | :TQ10007                 | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |        | S->P | BROADCAST  |
    |  54 |               INDEX FAST FULL SCAN| MGT_UNIT_RES_LINE_MAP_UK | 93763 |  1648K|    59   (0)| 00:00:01 |       |       |        |      |            |
    |  55 |            PX BLOCK ITERATOR      |                          |   346M|    59G|   411K  (1)| 01:35:58 |     1 |   385 |  Q1,08 | PCWC |            |
    |  56 |             TABLE ACCESS FULL     | RHS_PREMIUM_1            |   346M|    59G|   411K  (1)| 01:35:58 |     1 |   385 |  Q1,08 | PCWP |            |
    Predicate Information (identified by operation id):
       3 - access("BU2"."RESERVING_LINE_ID"="BL2"."RESERVING_LINE_ID"(+))
       9 - filter("RL"."RESERVING_LINE_TYPE"='BU')
      10 - access("RL"."RESERVING_CLASS_ID"="RC"."RESERVING_CLASS_ID"(+))
      11 - access("PREM"."BUSINESS_UNIT"="BU2"."BUSINESS_UNIT"(+) AND "PREM"."FINANCIAL_PRODUCT"="BU2"."PRODUCT"(+))
      16 - access("BU1"."RESERVING_LINE_ID"="BL1"."RESERVING_LINE_ID"(+))
      22 - filter("RL"."RESERVING_LINE_TYPE"='BU')
      23 - access("RL"."RESERVING_CLASS_ID"="RC"."RESERVING_CLASS_ID"(+))
      24 - access("PREM"."BUSINESS_UNIT"="BU1"."BUSINESS_UNIT"(+) AND "PREM"."PRODUCT"="BU1"."PRODUCT"(+))
      29 - access("MU2"."RESERVING_LINE_ID"="ML2"."RESERVING_LINE_ID"(+))
      34 - access("RL"."RESERVING_CLASS_ID"="RC"."RESERVING_CLASS_ID"(+))
      35 - filter("RL"."RESERVING_LINE_TYPE"='MCC')
      37 - access("PREM"."MANAGEMENT_UNIT"="MU2"."MANAGEMENT_UNIT"(+) AND "PREM"."FINANCIAL_PRODUCT"="MU2"."PRODUCT"(+))
      42 - access("MU1"."RESERVING_LINE_ID"="ML1"."RESERVING_LINE_ID"(+))
      47 - access("RL"."RESERVING_CLASS_ID"="RC"."RESERVING_CLASS_ID"(+))
      48 - filter("RL"."RESERVING_LINE_TYPE"='MCC')
      50 - access("PREM"."MANAGEMENT_UNIT"="MU1"."MANAGEMENT_UNIT"(+) AND "PREM"."PRODUCT"="MU1"."PRODUCT"(+))Please let me know if there is any possibilty.
    Regards,
    Sandy

    Big query - 9 tables, outer joins, parallel query option. Reading/joining views - steps 7, 20, etc?
    if you are reading most of the rows in both tables then hash joins are probably the most efficient way to read the data. The parallel query option may or may not be helping.
    Outer joins usually make queries slower. Views can also have th same effect, and will probably affect the execution plan.
    If you are reading views you can eliminate them by using the base tables to see how that affects performance. You can change the session parameter for DB_FILE_MULTIBLOCK_READ COUNT for more efficient full table scans if its set (the documentation and blog articles claim leaving it unset in the database is the most efficient use).
    Edited by: riedelme on Jun 6, 2011 8:26 AM

  • Hash unique performance.

    Hi,
    We are running 10.2.0.3.0 on Aix 5.3. We are seeing massive performance degredation with statements resolved by hash unique.
    A statement of the type
    update tab set col =
    (select distinct col
    from othertab
    where othertab.joincol = tab.joincol)
    will be resolved using a hash unique at the distinct point and will run very, very slowly.
    if we change the statement to two statements...
    insert into temptab
    (select distinct joincol, col
    from othertab);
    update tab
    set col = (select col from temptab where temptab.joincol = tab.joincol)
    Then performance will be exponentially quicker even though the insert will still do a hash unique.
    We have opened an SR, we have tried coding round the hash unique using group by, we have checked the hashing is not being done on disk, we have checked for swapping, we have set the work_area_size policy to manual and provided 1GB of physical memory for the session - only a fraction got used and the statement ran slowly.
    Any one any suggestions?

    We just upgraded from 9.2.0.2 to 10.2.0.3... and also experienced the same massive performance change. Updates in 9i taking 1-3 hours were showing 20-60 hours per the long run (OEM). We also noted our 4 and 8 cpu boxes hitting or staying very near 100% utilization. IO has been our main concern on this project, never cpu.
    The explain plan between 9i and 10G for all the update statements effected were the identiical with one exception... in 9i there was a SORT UNIQUE where as in 10G it was replaced with a HASH UNIQUE.
    We also found the same URL referenced above... setting this undocumented init parameter _gby_hash_aggregation_enabled to false resulted in the SORT UNIQUE to return and now the scripts are running even faster in 10G then in 9i now - about 1/3 faster.
    Note, our 9i used 8K block size… 10G is using 16K. Our tables have 10 of millions of records loaded every day so this was a critical issue for our project.
    Dave C

  • Maximum number of key/value pairs in btree or hash database

    It's not clear to me from the documentation what the limit is on the number of key/value pairs in a Btree or hash database. The documentation on logical record numbers says that the db_recno_t type is a 32-bit unsigned type, "which limits the number of logical records in a Queue or Recno database, and the maximum logical record which may be directly retrieved from a Btree database, to 4,294,967,295". What does "directly retrieved" mean in this sentence? Does this mean that Btree is limited to 4,294,967,295 key/vaue pairs? If so, is this also the limit for a hash database?

    Hi mcgarvek,
    In case of Queue, Recno and Btree configured for logical record numbers - you can do that by setting DB_RECNUM flag: http://www.oracle.com/technology/documentation/berkeley-db/db/api_c/db_set_flags.html#DB_RECNUM , the maximum number of records is 4,294,967,295 and after that limit, the next record will be inserted as record number 1.
    In case of Hash and Btree, the maximum database size depends on the page size selected by the application. Berkeley DB stores database file page numbers as unsigned 32-bit numbers and database file page sizes as unsigned 16-bit numbers. Using the maximum database page size of 65536, this results in a maximum database file size of 248 (256 terabytes).
    Database limits: http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_misc/dbsizes.html
    Logical record numbers: http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/logrec.html
    Regards,
    Bogdan Coman

  • Which structure is Oracle NoSQL used default? BTree or Hash ?

    Hello,
    Which structure is Oracle NoSQL used default? BTree or Hash ?
    Thank you for your answers.

    Oracle NoSQL Database uses Berkeley DB Java Edition as the storage engine. BDB JE only has a b-tree access method.
    Charles Lamb

  • HASH JOIN Issue - query performance issue

    Hello friends:
    I have a nested loop long query. When i execute this on Oracle 9i, the results comes back within no time (less than a sec) but the same query, same schema, the query takes over 20-30secs. Looking at the execution plan (pasted below) - the Oracle 10g is using HASH JOIN compared to NESTED LOOPS (Oracle 9i). The cost on 9i is much less than 10g due to the hash join form 10g --
    Here's the explain plan for -- How do i make 10g plan to use the one from 9i--the nested loop?
    Oracle 10g:
    SORT(AGGREGATE)               1     33
    HASH JOIN          25394     2082     68706
    MAT_VIEW ACCESS(FULL) GMDB.NODE_ATTRIBUTES     ANALYZED     17051     2082     56214
    VIEW          8318     1714180     10285080
    FILTER                    
    CONNECT BY(WITH FILTERING)                    
    Oracle 9i--
    SORT(AGGREGATE)               1     40     
    NESTED LOOPS          166     65     2600          
    VIEW          36     65     845               
    FILTER

    just noticed the "CONNECT BY" in the plan. connect by queries are special cases, should you should spell that out loud and clear for us next time. anyway, lots of problems in v10 with connect by:
    metalink Note:394358.1
    CONNECT BY SQL uses Full Table Scan In 10.2.0.2 - Used Index In earlier versions
    solution:
    alter session set "_optimizer_connect_by_cost_based"=false;
    and bugs related to connect by fixed in the 10.2.0.2 release (other than the bug from the note bug, which was introduced):
    metalink Note:358749.1
    and
    Note:3956141.8
    OR filter in CONNECT BY query may be applied at table level (v 10.1.0.3)

  • Optimizer=ALL_ROWS, PARTITION HASH, INDEX (RANGE SCAN) POOR PERFORMANCE?

    Our os is;
    SunOS 5.9
    and database is;
    Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - 64bit
    Our autotrace outputs are below also we have 10046 trace outputs;
    08:41:04 tcell_dev@SCME > set timing on
    08:41:19 tcell_dev@SCME > set autot on
    08:41:21 tcell_dev@SCME > SELECT lnpessv.PROFILE_ID FROM SCME.LNK_PROFILEENTITY_SUBSSERVVAR lnpessv
    08:41:25 2 WHERE lnpessv.SUBSCRIPTION_SERVICEVARIANT_ID = 1695083 ;
    PROFILE_ID
    1.400E+14
    1.600E+14
    Elapsed: 00:00:03.07
    Execution Plan
    0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=3 Bytes=51)
    1 0 PARTITION HASH (ALL) (Cost=3 Card=3 Bytes=51)
    2 1 INDEX (RANGE SCAN) OF 'PK_PROFILEENTITY_SUBSSERVVAR' (INDEX (UNIQUE)) (Cost=
    3 Card=3 Bytes=51)
    Statistics
    1 recursive calls
    0 db block gets
    1539 consistent gets
    514 physical reads
    0 redo size
    258 bytes sent via SQL*Net to client
    273 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    2 rows processed
    08:41:32 tcell_dev@SCME > SELECT lnpessv.PROFILE_ID FROM SCME.LNK_PROFILEENTITY_SUBSSERVVAR lnpessv
    08:41:43 2 WHERE lnpessv.SUBSCRIPTION_SERVICEVARIANT_ID = 169508 ;
    PROFILE_ID
    1.400E+14
    1.600E+14
    Elapsed: 00:00:04.01
    Execution Plan
    0 SELECT STATEMENT Optimizer=ALL_ROWS (Cost=3 Card=3 Bytes=51)
    1 0 PARTITION HASH (ALL) (Cost=3 Card=3 Bytes=51)
    2 1 INDEX (RANGE SCAN) OF 'PK_PROFILEENTITY_SUBSSERVVAR' (INDEX (UNIQUE)) (Cost=
    3 Card=3 Bytes=51)
    Statistics
    1 recursive calls
    0 db block gets
    1537 consistent gets
    512 physical reads
    0 redo size
    258 bytes sent via SQL*Net to client
    273 bytes received via SQL*Net from client
    2 SQL*Net roundtrips to/from client
    0 sorts (memory)
    0 sorts (disk)
    2 rows processed
    Here we see 97% wait time, and responce time is unexceptable; These are the waits from 10046 trace file;
    WAIT #1: nam='gc cr grant 2-way' ela= 783 p1=341 p2=67065 p3=1 obj#=169530 tim=571610438395
    WAIT #1: nam='db file sequential read' ela= 6924 file#=341 block#=67065 blocks=1 obj#=169530 tim=571610445466
    WAIT #1: nam='gc cr grant 2-way' ela= 564 p1=294 p2=86263 p3=1 obj#=169531 tim=571610446493
    WAIT #1: nam='db file sequential read' ela= 6629 file#=294 block#=86263 blocks=1 obj#=169531 tim=571610453158
    INDEX RANGE SCAN PK_PROFILEENTITY_SUBSSERVVAR PARTITION: 1 512 (cr=1537 pr=512 pw=0 time=4272017 us)
    This is the related tables properties;
    OWNER     SCME
    TABLE_NAME     LNK_PROFILEENTITY_SUBSSERVVAR
    TABLESPACE_NAME     DATA01
    STATUS     VALID
    PCT_FREE     10
    INI_TRANS     10
    MAX_TRANS     255
    INITIAL_EXTENT     65536
    MIN_EXTENTS     1
    MAX_EXTENTS     2147483645
    LOGGING     NO
    BACKED_UP     N
    NUM_ROWS     239587420
    BLOCKS     1587288
    EMPTY_BLOCKS     0
    AVG_SPACE     0
    CHAIN_CNT     0
    AVG_ROW_LEN     41
    AVG_SPACE_FREELIST_BLOCKS     0
    NUM_FREELIST_BLOCKS     0
    DEGREE     1
    INSTANCES     1
    CACHE     N
    TABLE_LOCK     ENABLED
    SAMPLE_SIZE     71876226
    LAST_ANALYZED     29.05.2006 23:21:24
    PARTITIONED     NO
    TEMPORARY     N
    SECONDARY     N
    NESTED     NO
    BUFFER_POOL     DEFAULT
    ROW_MOVEMENT     DISABLED
    GLOBAL_STATS     YES
    USER_STATS     NO
    SKIP_CORRUPT     DISABLED
    MONITORING     YES
    DEPENDENCIES     DISABLED
    COMPRESSION     DISABLED
    DROPPED     NO
    We are suspecting rac configuration and hash partition and index usage with rac.
    Any comments will be welcomed,
    Thank you.
    Tonguç

    this is the output of dbms_metadata.get_ddl for the table;
    CREATE TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR"
    (     "SUBSCRIPTION_SERVICEVARIANT_ID" NUMBER NOT NULL ENABLE NOVALIDATE,
         "PROFILE_ID" NUMBER NOT NULL ENABLE NOVALIDATE,
         "CREATED_BY_ID" NUMBER,
         "CREATED_DATE" DATE DEFAULT SYSDATE,
         "UPDATED_BY_ID" NUMBER,
         "UPDATED_DATE" DATE,
         CONSTRAINT "PK_PROFILEENTITY_SUBSSERVVAR" PRIMARY KEY ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54010"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54011"
    TABLESPACE "INDX02",
    PARTITION "SYS_P54012"
    TABLESPACE "INDX02") ;
    CREATE UNIQUE INDEX "SCME"."PK_PROFILEENTITY_SUBSSERVVAR" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ENABLE NOVALIDATE,
         CONSTRAINT "FK_LNK_PROF_REFERENCE_SDP_SUBS" FOREIGN KEY ("SUBSCRIPTION_SERVICEVARIANT_ID")
         REFERENCES "SCME"."SDP_SUBSCRIPTIONSERVICEVARIANT" ("SUBSCRIPTION_SERVICEVARIANT_ID") DEFERRABLE INITIALLY DEFERRED ENABLE NOVALIDATE
    ) PCTFREE 10 PCTUSED 40 INITRANS 10 MAXTRANS 255 NOCOMPRESS NOLOGGING
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "DATA01" ;
    CREATE INDEX "SCME"."LNK_PROFILEENTITY_SUB_HNDX3" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("SUBSCRIPTION_SERVICEVARIANT_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 2097152
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID")
    (PARTITION "SYS_P53501"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53502"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ;
    CREATE INDEX "SCME"."PROFILE_ID_NDX43" ON "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ("PROFILE_ID")
    PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING COMPUTE STATISTICS
    STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
    PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
    TABLESPACE "INDX03" ;
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" ADD CONSTRAINT "PK_PROFILEENTITY_SUBSSERVVAR" PRIMARY KEY ("SUBSCRIPTION_SERVICEVARIANT_ID", "PROFILE_ID")
    USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 NOLOGGING
    STORAGE(INITIAL 4194304
    BUFFER_POOL DEFAULT)
    TABLESPACE "INDX02" GLOBAL PARTITION BY HASH ("SUBSCRIPTION_SERVICEVARIANT_ID","PROFILE_ID")
    (PARTITION "SYS_P52989"
    TABLESPACE "INDX02",
    PARTITION "SYS_P52990"
    PARTITION "SYS_P53498"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53499"
    TABLESPACE "INDX02",
    PARTITION "SYS_P53500"
    TABLESPACE "INDX02") ENABLE NOVALIDATE;
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" MODIFY ("SUBSCRIPTION_SERVICEVARIANT_ID" NOT NULL ENABLE NOVALIDATE);
    ALTER TABLE "SCME"."LNK_PROFILEENTITY_SUBSSERVVAR" MODIFY ("PROFILE_ID" NOT NULL ENABLE NOVALIDATE);

  • Table Spool (Lazy Spool) & Hash Match (Aggregate) killing performance.

    Hi Folks,
    I have a query that takes about 5 minutes and I am not sure where the issue is. Is there anyway someone can give an insight to this query plan please? Here are the tables and indexes definitions:
    -----Table 1
    CREATE TABLE [dbo].[PropVal](
    [Item] [nvarchar](16) NOT NULL,
    [Symbol] [nvarchar](23) NOT NULL,
    [Date] [smalldatetime] NOT NULL,
    [Value] [nvarchar](max) NOT NULL
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    CREATE UNIQUE CLUSTERED INDEX [PropVal_PK] ON [dbo].[PropVal]
    [Symbol] ASC,
    [Item] ASC
    )GO
    -----Table 2
    CREATE TABLE [dbo].[Crons](
    [CronID] [nvarchar](23) NOT NULL,
    [Date] [smalldatetime] NOT NULL,
    [XMLBlob] [xml] NOT NULL,
    PRIMARY KEY CLUSTERED ([CronID] ASC )
    ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    GO
    CREATE NONCLUSTERED INDEX [test_idx_crons] ON [dbo].[Crons]
    ( [Date] ASC )
    INCLUDE ( [CronID]) 
    GO
    below is the script 
    SELECT  'CLIENTIDS' AS Item
      , Symbol
      , CONVERT(NCHAR(8), GETUTCDATE(), 112) AS Date
      , STUFF(CAST(( SELECT DISTINCT
                            ',' + [Value]
          FROM   DBO.PropVal WITH (NOLOCK)
          WHERE  [Symbol] IN (
                 SELECT DISTINCT
                        ( [Value] )
                 FROM    DBO.PropVal WITH (NOLOCK)
                 WHERE   [Item] = 'USERID'
                         AND [Value] NOT LIKE 'RIMES-%'
                         AND [Symbol] IN (
                              SELECT  DISTINCT a.[Symbol]
                              FROM    DBO.PropVal a, DBO.Crons b WITH (NOLOCK)
                              WHERE   a.[Item] = 'SYSTEM'
                                      AND a.[Symbol] = SUBSTRING(b.[CronID],1,CHARINDEX('.',b.[CronID])-1)
                                      AND b.[Date] > DATEADD(MONTH,-1,GETUTCDATE())
                                     AND a.[Value] = symbols.Symbol ) )
                         AND [Item] = 'CLIENTID'
                 FOR
                    XML PATH('')
                 ) AS varchar(MAX)), 1, 1, '') AS Value
    FROM    ( SELECT DISTINCT
                        [Value] AS Symbol
              FROM      DBO.PropVal WITH (NOLOCK)
              WHERE     [Item] = 'SYSTEM'
              AND       [Value] LIKE 'SYS-%'
            ) AS symbols
    UNION ALL
    SELECT  'USERIDS' AS Item
      , Symbol
      , CONVERT(NCHAR(8), GETUTCDATE(), 112) AS Date
      , STUFF(CAST(( SELECT DISTINCT
                            ',' + [Value]
          FROM   DBO.PropVal WITH (NOLOCK)
          WHERE  [Symbol] IN (
                 SELECT  [Symbol]
                 FROM    DBO.PropVal WITH (NOLOCK)
                 WHERE   [Item] = 'SYSTEM'
                         AND [Value] = symbols.Symbol )
          AND [Item] = 'USERID'
          AND [Value] NOT LIKE 'RIMES%'
          FOR
             XML PATH('')
          ) AS varchar(MAX)), 1, 1, '') AS Value
    FROM    ( SELECT DISTINCT
                        [Value] AS Symbol
              FROM      DBO.PropVal WITH (NOLOCK)
              WHERE     [Item] = 'SYSTEM'
              AND       [Value] LIKE 'SYS-%'
            ) AS symbols;

    Not that this is a fix to performance, but this query may not be doing what you want.  About 11 lines into the query you have a WHERE clause that reads
    WHERE [Item] = 'USERID'
    AND [Value] NOT LIKE 'RIMES-%'
    AND [Symbol] IN (
    SELECT DISTINCT a.[Symbol]
    FROM DBO.PropVal a, DBO.Crons b WITH (NOLOCK)
    WHERE a.[Item] = 'SYSTEM'
    AND a.[Symbol] = SUBSTRING(b.[CronID],1,CHARINDEX('.',b.[CronID])-1)
    AND b.[Date] > DATEADD(MONTH,-1,GETUTCDATE())
    AND a.[Value] = symbols.Symbol ) )
    AND [Item] = 'CLIENTID'
    Notice that that is of the form
    WHERE [Item] = 'USERID'
    AND <some other stuff>
    AND [Item] = 'CLIENTID'
    So, since no row can have Item = 'USERID' and have Item = 'CLIENTID', whis WHERE clause will never return any rows.
    Tom

  • Why append opration will not perform for hashed table???

    could you pls explain why append is not working for  hashed table while it is working for sort and hashed.......
    Moderator Message: Interview-type questions are not allowed. Read the Rules of Engagement of these forum to avoid getting your ID deleted.
    Edited by: kishan P on Mar 1, 2012 11:25 AM

    Hello,
    See the hashed tables does not support index operations like in standard and sorted tables rather its individual entries are accessed by key. The hashed internal table has been developed specifically using hashing algorithm. In other words, APPEND statement will not work in hashed internal tables but only in standard tables.
    The processing of hashed tables are undertaken by using a KEY whereas for the standard table you may use the key to access it contents or not.
    For more info you can refer to following link below -
    [http://help.sap.com/saphelp_nw70/helpdata/en/fc/eb35de358411d1829f0000e829fbfe/content.htm]
    Hope this helps !

  • BTREE and duplicate data items : over 300 people read this,nobody answers?

    I have a btree consisting of keys (a 4 byte integer) - and data (a 8 byte integer).
    Both integral values are "most significant byte (MSB) first" since BDB does key compression, though I doubt there is much to compress with such small key size. But MSB also allows me to use the default lexical order for comparison and I'm cool with that.
    The special thing about it is that with a given key, there can be a LOT of associated data, thousands to tens of thousands. To illustrate, a btree with a 8192 byte page size has 3 levels, 0 overflow pages and 35208 duplicate pages!
    In other words, my keys have a large "fan-out". Note that I wrote "can", since some keys only have a few dozen or so associated data items.
    So I configure the b-tree for DB_DUPSORT. The default lexical ordering with set_dup_compare is OK, so I don't touch that. I'm getting the data items sorted as a bonus, but I don't need that in my application.
    However, I'm seeing very poor "put (DB_NODUPDATA) performance", due to a lot of disk read operations.
    While there may be a lot of reasons for this anomaly, I suspect BDB spends a lot of time tracking down duplicate data items.
    I wonder if in my case it would be more efficient to have a b-tree with as key the combined (4 byte integer, 8 byte integer) and a zero-length or 1-length dummy data (in case zero-length is not an option).
    I would loose the ability to iterate with a cursor using DB_NEXT_DUP but I could simulate it using DB_SET_RANGE and DB_NEXT, checking if my composite key still has the correct "prefix". That would be a pain in the butt for me, but still workable if there's no other solution.
    Another possibility would be to just add all the data integers as a single big giant data blob item associated with a single (unique) key. But maybe this is just doing what BDB does... and would probably exchange "duplicate pages" for "overflow pages"
    Or, the slowdown is a BTREE thing and I could use a hash table instead. In fact, what I don't know is how duplicate pages influence insertion speed. But the BDB source code indicates that in contrast to BTREE the duplicate search in a hash table is LINEAR (!!!) which is a no-no (from hash_dup.c):
         while (i < hcp->dup_tlen) {
              memcpy(&len, data, sizeof(db_indx_t));
              data += sizeof(db_indx_t);
              DB_SET_DBT(cur, data, len);
              * If we find an exact match, we're done. If in a sorted
              * duplicate set and the item is larger than our test item,
              * we're done. In the latter case, if permitting partial
              * matches, it's not a failure.
              *cmpp = func(dbp, dbt, &cur);
              if (*cmpp == 0)
                   break;
              if (*cmpp < 0 && dbp->dup_compare != NULL) {
                   if (flags == DB_GET_BOTH_RANGE)
                        *cmpp = 0;
                   break;
    What's the expert opinion on this subject?
    Vincent
    Message was edited by:
    user552628

    Hi,
    The special thing about it is that with a given key,
    there can be a LOT of associated data, thousands to
    tens of thousands. To illustrate, a btree with a 8192
    byte page size has 3 levels, 0 overflow pages and
    35208 duplicate pages!
    In other words, my keys have a large "fan-out". Note
    that I wrote "can", since some keys only have a few
    dozen or so associated data items.
    So I configure the b-tree for DB_DUPSORT. The default
    lexical ordering with set_dup_compare is OK, so I
    don't touch that. I'm getting the data items sorted
    as a bonus, but I don't need that in my application.
    However, I'm seeing very poor "put (DB_NODUPDATA)
    performance", due to a lot of disk read operations.In general, the performance would slowly decreases when there are a lot of duplicates associated with a key. For the Btree access method lookups and inserts have a O(log n) complexity (which implies that the search time is dependent on the number of keys stored in the underlying db tree). When doing put's with DB_NODUPDATA leaf pages have to be searched in order to determine whether the data is not a duplicate. Thus, giving the fact that for each given key (in most of the cases) there is a large number of data items associated (up to thousands, tens of thousands) an impressive amount of pages have to be brought into the cache to check against the duplicate criteria.
    Of course, the problem of sizing the cache and databases's pages arises here. Your size setting for these measures should tend to large values, this way the cache would be fit to accommodate large pages (in which hundreds of records should be hosted).
    Setting the cache and the page size to their ideal values is a process of experimenting.
    http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/pagesize.html
    http://www.oracle.com/technology/documentation/berkeley-db/db/ref/am_conf/cachesize.html
    While there may be a lot of reasons for this anomaly,
    I suspect BDB spends a lot of time tracking down
    duplicate data items.
    I wonder if in my case it would be more efficient to
    have a b-tree with as key the combined (4 byte
    integer, 8 byte integer) and a zero-length or
    1-length dummy data (in case zero-length is not an
    option). Indeed, these should be the best alternative, but testing must be done first. Try this approach and provide us with feedback.
    You can have records with a zero-length data portion.
    Also, you could provide more information on whether or not you're using an environment, if so, how did you configure it etc. Have you thought of using multiple threads to load the data ?
    Another possibility would be to just add all the
    data integers as a single big giant data blob item
    associated with a single (unique) key. But maybe this
    is just doing what BDB does... and would probably
    exchange "duplicate pages" for "overflow pages"This is a terrible approach since bringing an overflow page into the cache is more time consuming than bringing a regular page, and thus performance penalty results. Also, processing the entire collection of keys and data implies more work from a programming point of view.
    Or, the slowdown is a BTREE thing and I could use a
    hash table instead. In fact, what I don't know is how
    duplicate pages influence insertion speed. But the
    BDB source code indicates that in contrast to BTREE
    the duplicate search in a hash table is LINEAR (!!!)
    which is a no-no (from hash_dup.c):The Hash access method has, as you observed, a linear search (and thus a search time and lookup time proportional to the number of items in the buckets, O(1)). Combined with the fact that you don't want duplicate data than hash using the hash access method may not improve performance.
    This is a performance/tunning problem and it involves a lot of resources from our part to investigate. If you have a support contract with Oracle, then please don't hesitate to put up your issue on Metalink or indicate that you want this issue to be taken in private, and we will create an SR for you.
    Regards,
    Andrei

Maybe you are looking for