Query is doing full table scan

Hi All,
The below query is doing full table scan. So many threads from application trigger this query and doing full table scan. Can you please tell me how to improve the performance of this query?
Env is 11.2.0.3 RAC (4 node). Unique index on VZ_ID, LOGGED_IN. The table row count is 2,501,103.
Query is :-
select ccagentsta0_.LOGGED_IN as LOGGED1_404_, ccagentsta0_.VZ_ID as VZ2_404_, ccagentsta0_.ACTIVE as ACTIVE404_, ccagentsta0_.AGENT_STATE as AGENT4_404_,
ccagentsta0_.APPLICATION_CODE as APPLICAT5_404_, ccagentsta0_.CREATED_ON as CREATED6_404_, ccagentsta0_.CURRENT_ORDER as CURRENT7_404_,
ccagentsta0_.CURRENT_TASK as CURRENT8_404_, ccagentsta0_.HELM_ID as HELM9_404_, ccagentsta0_.LAST_UPDATED as LAST10_404_, ccagentsta0_.LOCATION as LOCATION404_,
ccagentsta0_.LOGGED_OUT as LOGGED12_404_, ccagentsta0_.SUPERVISOR_VZID as SUPERVISOR13_404_, ccagentsta0_.VENDOR_NAME as VENDOR14_404_
from AGENT_STATE ccagentsta0_ where ccagentsta0_.VZ_ID='v790531'  and ccagentsta0_.ACTIVE='Y';
Table Scan                                                       AGENT_STATE                                                2.366666667
Table Scan                                                       AGENT_STATE                                                0.3666666667
Table Scan                                                       AGENT_STATE                                                1.633333333
Table Scan                                                       AGENT_STATE                                                       0.75
Table Scan                                                       AGENT_STATE                                                1.866666667
Table Scan                                                       AGENT_STATE                                                2.533333333
Table Scan                                                       AGENT_STATE                                                0.5333333333
Table Scan                                                       AGENT_STATE                                                       1.95
Table Scan                                                       AGENT_STATE                                                        0.8
Table Scan                                                       AGENT_STATE                                                0.2833333333
Table Scan                                                       AGENT_STATE                                                1.983333333
Table Scan                                                       AGENT_STATE                                                        2.5
Table Scan                                                       AGENT_STATE                                                1.866666667
Table Scan                                                       AGENT_STATE                                                1.883333333
Table Scan                                                       AGENT_STATE                                                        0.9
Table Scan                                                       AGENT_STATE                                                2.366666667
But the explain plan shows the query is taking the index
Explain plan output:-
PLAN_TABLE_OUTPUT
Plan hash value: 1946142815
| Id  | Operation                   | Name            | Rows  | Bytes | Cost (%C
PU)| Time     |
PLAN_TABLE_OUTPUT
|   0 | SELECT STATEMENT            |                 |     1 |   106 |   244
(0)| 00:00:03 |
|*  1 |  TABLE ACCESS BY INDEX ROWID| AGENT_STATE     |     1 |   106 |   244
(0)| 00:00:03 |
|*  2 |   INDEX RANGE SCAN          | AGENT_STATE_IDX |   229 |       |     4
(0)| 00:00:01 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
   1 - filter("CCAGENTSTA0_"."ACTIVE"='Y')
   2 - access("CCAGENTSTA0_"."VZ_ID"='v790531')
The values (VZ_ID) i have given are dummy values picked from the table. I dont get the actual values since the query is coming with bind variables. Please let me know your suggestion on this.
Thanks,
Mani

Hi,
But I am not getting what is the issue..its a simple select query and index is there on one of the leading columns (VZ_ID --- PK). Explain plan says its using its using Index and it only select fraction of rows from the table. Then why it is doing FTS. For Optimizer, why its like a query doing FTS.
The rule-based optimizer would have  picked the plan with the index. The cost-based optimizer, however, is picking the plan with the lowest cost. Apparently, the lowest cost plan is the one with the full table scan. And the optimizer isn't necessarily wrong about this.
Reading data from a table via index probes is only efficient when selecting a relatively small percentage of rows. For larger percentages, a full table scan is generally better.
Consider a simple example: a query that selects from a table with biographies for all people on the planet. Suppose you are interested in all people from a certain country.
select * from all_people where country='Vatican'
would only return only 800 rows (as Vatican is an extremely small country with population of just 800 people). For this case, obviously, using an index would be very efficient.
Now if we run this query:
select * from all_people where contry = 'India',
we'd be getting over a billion of rows. For this case, a full table scan would be several thousand times faster.
Now consider the third case:
select * from all_people where country = :b1
What plan should the optimizer choose? The value of :b1 bind variable is generally not known during the parse time, it will be passed by the user when the query is already parsed, during run-time.
In this case, one of two scenarios takes place: either the optimizer relies on some built-in default selectivities (basically, it takes a wild guess), or the optimizer postpones taking the final decision until the
first time the query is run, 'peeks' the value of the bind, and optimizes the query for this case.
In means, that if the first time the query is parsed, it was called with :b1 = 'India', a plan with a full table scan will be generated and cached for subsequent usage. And until the cursor is aged out of library cache
or invalidated for some reason, this will be the plan for this query.
If the first time it was called with :b1='Vatican', then an index-based plan will be picked.
Either way, bind peeking only gives good results if the subsequent usage of the query is the same kind as the first usage. I.e. in the first case it will be efficient, if the query would always be run for countries with big popultions.
And in the second case, if it's always run for countries with small populations.
This mechanism is called 'bind peeking' and it's one of the most common causes of performance problems. In 11g, there are more sophisticated mechanisms, such a cardinality feedback, but they don't always work as expected.
This mechanism is the most likely explanation for your issue. However, without proper diagnostic information we cannot be 100% sure.
Best regards,
  Nikolay

Similar Messages

  • Select statement in a function does Full Table Scan

    All,
    I have been coding a stored procedure that writes 38K rows in less than a minute. If I add another column which requires call to a package and 4 functions within that package, it runs for about 4 hours. I have confirmed that due to problems in one of the functions, the code does full table scans. The package and all of its functions were written by other contractors who have been long gone.
    Please note that case_number_in (VARCHAR2) and effective_date_in (DATE) are parameters sent to the problem function and I have verified through TOAD’s debugger that their values are correct.
    Table named ps2_benefit_register has over 40 million rows but case_number is an index for that table.
    Table named ps1_case_fs has more than 20 million rows but also uses case_number as an index.
    Select #1 – causes full table scan runs and writes 38K rows in a couple of hours.
    {case}
    SELECT max(a2.application_date)
    INTO l_app_date
    FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
    WHERE a2.case_number = case_number_in and
    a1.case_number = a2.case_number and
    a2.application_date <= effective_date_in and
    a1.DOCUMENT_TYPE = 'F';
    {case}
    Select #2 – runs – hard coding values makes the code to write the same 38K rows in a few minutes.
    {case}
    SELECT max(a2.application_date)
    INTO l_app_date
    FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
    WHERE a2.case_number = 'A006438' and
    a1.case_number = a2.case_number and
    a2.application_date <= '01-Apr-2009' and
    a1.DOCUMENT_TYPE = 'F';
    {case}
    Why using the values in the passed parameter in the first select statement causes full table scan?
    Thank you for your help,
    Seyed
    Edited by: user11117178 on Jul 30, 2009 6:22 AM
    Edited by: user11117178 on Jul 30, 2009 6:23 AM
    Edited by: user11117178 on Jul 30, 2009 6:24 AM

    Hello Dan,
    Thank you for your input. The function is not determinsitic, therefore, I am providing you with the explain plan. By version number, if you are refering to the Database version, we are running 10g.
    PLAN_TABLE_OUTPUT
    Plan hash value: 2132048964
    | Id  | Operation                     | Name                    | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT              |                         |   324K|    33M|  3138   (5)| 00:00:38 |       |       |
    |*  1 |  HASH JOIN                    |                         |   324K|    33M|  3138   (5)| 00:00:38 |       |       |
    |   2 |   BITMAP CONVERSION TO ROWIDS |                         |     3 |     9 |     1   (0)| 00:00:01 |       |       |
    |*  3 |    BITMAP INDEX FAST FULL SCAN| IDX_PS2_ACTION_TYPES    |       |       |            |          |       |       |
    |   4 |   PARTITION RANGE ITERATOR    |                         |   866K|    87M|  3121   (4)| 00:00:38 |   154 |   158 |
    |   5 |    TABLE ACCESS FULL          | PS2_FS_TRANSACTION_FACT |   866K|    87M|  3121   (4)| 00:00:38 |   154 |   158 |
    Predicate Information (identified by operation id):
       1 - access("AL1"."ACTION_TYPE_ID"="AL2"."ACTION_TYPE_ID")
       3 - filter("AL2"."ACTION_TYPE"='1' OR "AL2"."ACTION_TYPE"='2' OR "AL2"."ACTION_TYPE"='S')
    Thank you very much,
    Seyed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

  • Why does query do a full table scan?

    I have a simple select query that filters on the last 10 or 11 days of data from a table. In the first case it executes in 1 second. In the second case it is taking 15+ minutes and still not done.
    I can tell that the second query (11 days) is doing a full table scan.
    - Why is this happening? ... I guess some sort of threshold calculation???
    - Is there a way to prevent this? ... or encourage Oracle to play nice.
    I find it confusing from a front end/query perspective to get vastly different performance.
    Jason
    Oracle 10g
    Quest Toad 10.6
    CREATE TABLE delme10 AS
    SELECT *
    FROM ed_visits
    WHERE first_contact_dt >= TRUNC(SYSDATE-10,'D');
    Plan hash value: 915912709
    | Id  | Operation                    | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
    |   0 | CREATE TABLE STATEMENT       |                   |  4799 |  5534K|  4951   (1)| 00:01:00 |
    |   1 |  LOAD AS SELECT              | DELME10           |       |       |            |          |
    |   2 |   TABLE ACCESS BY INDEX ROWID| ED_VISITS         |  4799 |  5534K|  4796   (1)| 00:00:58 |
    |*  3 |    INDEX RANGE SCAN          | NDX_ED_VISITS_020 |  4799 |       |    15   (0)| 00:00:01 |
    Predicate Information (identified by operation id):
       3 - access("FIRST_CONTACT_DT">=TRUNC(SYSDATE@!-10,'fmd'))
    CREATE TABLE delme11 AS
    SELECT *
    FROM ed_visits
    WHERE first_contact_dt >= TRUNC(SYSDATE-11,'D');
    Plan hash value: 1113251513
    | Id  | Operation              | Name      | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
    |   0 | CREATE TABLE STATEMENT |           | 25157 |    28M| 14580   (1)| 00:02:55 |        |      |            |
    |   1 |  LOAD AS SELECT        | DELME11   |       |       |            |          |        |      |            |
    |   2 |   PX COORDINATOR       |           |       |       |            |          |        |      |            |
    |   3 |    PX SEND QC (RANDOM) | :TQ10000  | 25157 |    28M| 14530   (1)| 00:02:55 |  Q1,00 | P->S | QC (RAND)  |
    |   4 |     PX BLOCK ITERATOR  |           | 25157 |    28M| 14530   (1)| 00:02:55 |  Q1,00 | PCWC |            |
    |*  5 |      TABLE ACCESS FULL | ED_VISITS | 25157 |    28M| 14530   (1)| 00:02:55 |  Q1,00 | PCWP |            |
    Predicate Information (identified by operation id):
       5 - filter("FIRST_CONTACT_DT">=TRUNC(SYSDATE@!-11,'fmd'))

    Hi Jason,
    I think you're right with kind of "threshold". You can verify CBO costing with event 10053 enabled. There are many possible ways to change this behaviour. Most straightforward would be probably INDEX hint, but you can also change some index-cost related parameters, check histograms, decrease degree of paralellism on table, create stored outline, etc.
    Lukasz

  • Query doing full table scan

    Hai all,
    10.2.0.4 on solaris 10
    SELECT sum(RechargeForPrepaid/10000), to_date(substr (TIMESTAMP, 1,8),'YYYY/MM/DD')
    FROM medt.crm_t  WHERE to_date(substr (TIMESTAMP, 1,8),'YYYY/MM/DD') >= trunc(sysdate)-1 and tradetype != '0' group by to_date(substr (TIMESTAMP, 1,8),'YYYY/MM/DD');The explain shows that it performs a full table scan on crm_t . I created indexes on the column
    timestamp and tradetype too . collected stats too. but still it is doing a full table scan.
    Please guide
    Thanks
    Kai

    sybrand_b wrote:
    The column is wrongly named --> timestamp is a reserved word.True:
    SQL> select * from v$reserved_words where keyword = 'TIMESTAMP'
      2  /
    KEYWORD                                                              LENGTH
    TIMESTAMP                                                                 9
    1 row selected.
    It is also of the wrong type--> dates shouldn't be stored as varchar2.All we know, is that the column is treated as if it is a VARCHAR2. It doesn't have to be a varchar2, because he might be relying on some implicit datatype conversion.
    The design of this table is a complete mess.
    Drop it and redesign.You'd better tell that to Oracle as well then :-) :
    SQL> desc user_objects
    Name                                                                      Null?    Type
    OBJECT_NAME                                                                        VARCHAR2(128)
    SUBOBJECT_NAME                                                                     VARCHAR2(30)
    OBJECT_ID                                                                          NUMBER
    DATA_OBJECT_ID                                                                     NUMBER
    OBJECT_TYPE                                                                        VARCHAR2(18)
    CREATED                                                                            DATE
    LAST_DDL_TIME                                                                      DATE
    TIMESTAMP                                                                          VARCHAR2(19)
    STATUS                                                                             VARCHAR2(7)
    TEMPORARY                                                                          VARCHAR2(1)
    GENERATED                                                                          VARCHAR2(1)
    SECONDARY                                                                          VARCHAR2(1)My point is that the TIMESTAMP datatype was introduced in version 9, and versions prior to that were free to use the name "TIMESTAMP". And all those older applications still function. A redesign would be ideal, but maybe not economically feasible. Oracle certainly didn't choose a redesign.
    If you are going to build a new application, then I agree that you'd better not use that reserved word anymore.
    Regards,
    Rob.

  • Update Query is Performing Full table Scan of 1 Millions Records

    Hello Everyboby I have one update query ,
    UPDATE tablea SET
              task_status = 12
              WHERE tablea.link_id >0
              AND tablea.task_status <> 0
              AND tablea.event_class='eventexception'
              AND Exists(SELECT 1 from tablea ltask where ltask.task_id=tablea.link_id
              AND ltask.task_status = 0)
    When I do explain plan it shows following result...
    Execution Plan
    0 UPDATE STATEMENT Optimizer=CHOOSE
    1 0 UPDATE OF 'tablea'
    2 1 FILTER
    3 2 TABLE ACCESS (FULL) OF 'tablea'
    4 2 TABLE ACCESS (BY INDEX ROWID) OF 'tablea'
    5 4 INDEX (UNIQUE SCAN) OF 'PK_tablea' (UNIQUE)
    NOW tablea may have more than 10 MILLION Records....This would take hell of time even if it has to
    update 2 records....please suggest me some optimal solutions.....
    Regards
    Mahesh

    I see your point but my question or logic say i have index on all columns used in where clauses so i find no reason for oracle to do full table scan,,,,
    UPDATE tablea SET
    task_status = 12
    WHERE tablea.link_id >0
    AND tablea.task_status <> 0
    AND tablea.event_class='eventexception'
    AND Exists(SELECT 1 from tablea ltask where ltask.task_id=tablea.link_id
    AND ltask.task_status = 0)
    I am clearly statis where task_status <> 0 and event_class= something and tablea.link_id >0
    so ideal case FOR optimizer should be
    Step 1)Select all the rowid having this condition...
    Step 2)
    For each row in rowid get all the row where task_status=0
    and where taskid=linkid of rowid selected above...
    Step 3)While looping for each rowid if it find any condition try for rowid obtained from ltask in task 2 update that record....
    I want to have this kind of plan,,,,,does anyone know how to make oracle obtained this kind of plan......
    It is try FULL TABLE SCAN is harmfull alteast not better than index scan.....

  • Query to identify full table scans in progress

    Does anybody have a query that would help me identify:
    1) Full table scans in progress.
    2) Long running queries in progress.
    Thanks,
    Thomas
    null

    Does anybody have a query that would help me identify:
    1) Full table scans in progress.Not sure.
    2) Long running queries in progressDon’t have a query readily available, but you can write one based on the following –
    Try querying the view V$SESSION_LONGOPS. You will need to join this to V$SQL using SQL_ADDRESS to identify all the SQL’s running for more than ‘x’ minutes.
    Current System Time - V$SESSION_LONGOPS.Start_Time should give you the duration.
    Shailender Mehta

  • Function based indexes doing full table scan

    Guys,
    I am testing function based indexes and whatever I do
    it is doing a full table scan.
    1)I have set the following init parameters as
    QUERY_REWRITE_ENABLED=TRUE
    QUERY_REWRITE_INTEGRITY=TRUSTED
    2)CREATE INDEX i3 ON emp(UPPER(ename));
    3) ANALYZE TABLE emp COMPUTE STATISTICS
    ANALYZE INDEX I3 COMPUTE STATISTICS
    4) DELETE plan_table;
    5) EXPLAIN PLAN SET statement_id='Test1' FOR
    SELECT ename FROM emp WHERE UPPER(ename) = 'KING';
    6) SELECT LPAD(' ',2*level-2)||operation||' '||options||' '||object_name
    query_plan
    FROM plan_table
    WHERE statement_id='Test1'
    CONNECT BY prior id = parent_id
    START WITH id = 0 order by id
    7) And the query plan shows as
    SELECT STATEMENT
    TABLE ACCESS FULL EMP
    I am using 9.0.1.4 !!!
    Any help is appreciated !!!
    Regards,
    A.Kishore

    One of the many new features in Oracle 8i is the Function-Based Index (we will refrain from using FBI, but only just). This allows the DBA to create indexes on functions or expressions; these functions can be user generated pl/sql functions, standard SQL functions (non-aggregate only) or even a C callout.
    A classic problem the DBA faces in SQL Tuning is how to tune those queries that use function calls in the where clause, and result in indexes created on these columns not to be used.
    Example
    Standard B-Tree index on SURNAME with cost based optimizer
    create index non_fbi on sale_contacts (surname);
    analyze index non_fbi compute statistics;
    analyze table sale_contacts compute statistics;
    SELECT count(*) FROM sale_contacts
    WHERE UPPER(surname) = 'ELLISON';
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=1 Bytes=17)
    1 0 SORT (AGGREGATE)
    2 1 TABLE ACCESS (FULL) OF 'SALES_CONTACTS' (Cost=3 Card=16 Bytes=272)
    Now we use a function based index
    create index fbi on sale_contacts (UPPER(surname));
    analyze index fbi compute statistics;
    analyze table sale_contacts compute statistics;
    SELECT count(*) FROM sale_contacts WHERE UPPER(surname) = 'ELLISON';
    Execution Plan
    0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1 Bytes=17)
    1 0 SORT (AGGREGATE)
    2 1 INDEX (RANGE SCAN) OF 'FBI' (NON-UNIQUE) (Cost=2 Card=381 Bytes=6477)
    The function-based index has forced the optimizer to use index range scans (retuning zero or more rowids) on the surname column rather than doing a full table scan (non-index lookup). Optimal performance does vary depending on table size, uniqueness and selectivity of columns, use of fast full table scans etc. Therefore try both methods to gain optimal performance in your database.
    It is important to remember that the function-based B*Tree index does not store the expression results in the index but uses an "expression tree". The optimizer performs expression matching by parsing the expression used in the SQL statement and comparing the results against the expression-tree values in the function-based index. This comparison IS case sensitive (ignores spaces) and therefore your function-based index expressions should match expressions used in the SQL statement where clauses.
    Init.ora Parameters
    The following parameter must be set in your parameter file: QUERY_REWRITE_INTEGRITY = TRUSTED
    QUERY_REWRITE_ENABLED = TRUE
    COMPATIBLE = 8.1.0.0.0 (or higher)
    Grants
    Grants To create function-based indexes the user must be granted CREATE INDEX and QUERY REWRITE, or alternatively be granted CREATE ANY INDEX and GLOBAL QUERY REWRITE. The index owner must have EXECUTE access on the function used for the index. If execute access is revoked then the function-based index will be "disabled" (see dba_indexes).
    Disabled Indexes
    If your function-based index has a status of "disabled" the DBA can do one of the following:
    a) drop and create the index (take note of its current settings)
    b) alter index enable, function-based indexes only, also use disable keyword as required
    c) alter index unusable.
    Queries on a DISABLED index fail if the optimizer chooses to use the index.Here is an example ORA error:
    ERROR at line 1: ORA-30554: function-based index MYUSER.FBI is disabled.
    All DML operations on a DISABLED index also fail unless the index is also marked UNUSABLE and the initialization parameter SKIP_UNUSABLE_INDEXES is set to true.
    Some more Examples
    CREATE INDEX expression_ndx
    ON mytable ((mycola + mycolc) * mycolb);
    SELECT mycolc FROM mytable
    WHERE (mycola + mycolc) * mycolb <= 256;
    ..or a composite index..
    CREATE INDEX example_ndx
    ON myexample (mycola, UPPER(mycolb), mycolc);
    SELECT mycolc FROM myexample
    WHERE mycola = 55 AND UPPER(mycolb) = 'JONES';
    Restriction & Rule Summary
    The following restrictions apply to function based indexes. You may not index:
    a) LOB columns
    b) REF
    c) Nested table column
    d) Objects types with any of the above data types.
    Function-based indexes must always follow these rules:
    a) Cost Based optimizer only, must generate statistics after the index is created
    b) Can not store NULL values (function can not return NULL under any circumstance)
    c) If a user defined pl/sql routine is used for the function-based index, and is invalidated, the index will become "disabled"
    d) Functions must be deterministic (always return the same value for a known input)
    e) The index owner must have "execute" access on function used in the function-based index. Revocation of the privilege will render the index "disabled"
    f) May have a B-Tree and Bitmap index type only
    g) Can not use expressions that are based on aggregate functions, ie. SUM, AVG etc.
    h) To alter a function-based index as enabled, the function used must be valid, deterministic and the signature of the function matches the signature of the function when it was created.
    Joel P�rez

  • Update doing full table scan and taking long time

    Hi All,
    I am running an update statement which is doing a full table scan.
    UPDATE Database.TABLE AS T
    SET COMMENTS = CAST(CAST(COALESCE(T.COMMENTS,0) AS INTEGER) + 1 AS
    CHARACTER)
    WHERE T.TRACKINGPOINT = 'NDEL'
    AND T.REFERENCENUMBER =
    SUBSTRING(Root.XML.EE_EAI_MESSAGE.ReferenceNumber || '
    ' FROM 1 FOR 32);
    Any advice.
    Regards,
    Umair

    Mustafa,
    No Developer is writing it in his program.
    Regards,
    Umair

  • "db file scattered read" too high and Query going for full table scan-Why ?

    Hi,
    I had a big table of around 200mb and had a index on it.
    In my query I am using the where clause which has to use the
    index. I am neither using any not null condition
    nor using any function on the index fields.
    Still my query is not using the index.
    It is going for full table scan.
    Also the statspack report is showing the
    "db file scattered read" too high.
    Can any body help and suggest me why this is happenning.
    Also tell me the possible solution for it.
    Thanks
    Arun Tayal

    "db file scattered read" are physical reads/multi block reads. This wait occurs when the session reading data blocks from disk and writing into the memory.
    Take the execution plan of the query and see what is wrong and why the index is not being used.
    However, FTS are not always bad. By the way, what is your db_block_size and db_file_multiblock_read_count values?
    If those values are set to high, Optimizer always favour FTS thinking that reading multiblock is always faster than single reads (index scans).
    Dont see oracle not using index, just find out why oracle is not using index. Use the INDEX hint to force optimizer to use index. Take the execution with/witout index and compare the cardinality,cost and of course, logical reads.
    Jaffar
    Message was edited by:
    The Human Fly

  • How can this query avoid full table scans?

    It is difficult to avoid full table scans in the following query because the values of column STATUS reiterant numbers. There are only 10 numbers values for the STATUS column (1..10)
    But the table is very large. there are more than 1 million rows in it. A full table scanning consumes too much time.
    How can this query avoid full table scans?
    Thank you
    SELECT SYNC,CUS_ID INTO V_SYNC,V_CUS_ID FROM CONSUMER_MSG_IDX
                      WHERE CUS_ID = V_TYPE_CUS_HEADER.CUS_ID AND
                            ADDRESS_ID = V_TYPE_CUS_HEADER.ADDRESS_ID AND
                            STATUS =! 8;Edited by: junez on Jul 23, 2009 7:30 PM

    Your code had an extra AND. I also replaced the "not equal" operator, which has display problems with the forum software
    SELECT SYNC,CUS_ID
       INTO V_SYNC,V_CUS_ID
      FROM CONSUMER_MSG_IDX
    WHERE CUS_ID = V_TYPE_CUS_HEADER.CUS_ID AND
           ADDRESS_ID = V_TYPE_CUS_HEADER.ADDRESS_ID AND
           STATUS != 8;Are you sure this query is doing a table scan? Is there an index on CUS_ID, ADDRESS_ID? I would think that would be mostly unique. So I'm not sure why you think the STATUS column is causing problems. It would seem to just be a non-selective additional filter.
    Justin

  • Slow query due to large table and full table scan

    Hi,
    We have a large Oracle database, v 10g. Two of the tables in the database have over one million rows.
    We have a few queries which take a lot of time to execute. Not always though, it that seems when load is high the queries tend
    to take much longer. Average time may be 1 or 2 seconds, but maxtime can be up to 2 minutes.
    We have now used Oracle Grid to help us examine the queries. We have found that some of the queries require two or three full table scans.
    Two of the full table scans are of the two large tables mentioned above.
    This is an example query:
    SELECT table1.column, table2.column, table3.column
    FROM table1
    JOIN table2 on table1.table2Id = table2.id
    LEFT JOIN table3 on table2.table3id = table3.id
    WHERE table1.id IN(
    SELECT id
    FROM (
    (SELECT a.*, rownum rnum FROM(
    SELECT table1.id
    FROM table1,
    table2,
    table3
    WHERE
    table1.table2id = table2.id
    AND
    table2.table3id IS NULL OR table2.table3id = :table3IdParameter
    ) a
    WHERE rownum <= :end))
    WHERE rnum >= :start
    Table1 and table2 are the large tables in this example. This query starts two full table scans on those tables.
    Can we avoid this? We have, what we think are, the correct indexes.
    /best regards, Håkan

    >
    Hi Håkan - welcome to the forum.
    We have a large Oracle database, v 10g. Two of the tables in the database have over one million rows.
    We have a few queries which take a lot of time to execute. Not always though, it that seems when load is high the queries tend
    to take much longer. Average time may be 1 or 2 seconds, but maxtime can be up to 2 minutes.
    We have now used Oracle Grid to help us examine the queries. We have found that some of the queries require two or three full table scans.
    Two of the full table scans are of the two large tables mentioned above.
    This is an example query:Firstly, please read the forum FAQ - top right of page.
    Please format your SQL using tags [code /code].
    In order to help us to help you.
    Please post table structures - relevant (i.e. joined, FK, PK fields only) in the form - note use of code tags - we can just run table create script.
    CREATE TABLE table1
      Field1  Type1,
      Field2  Type2,
    FieldN  TypeN
    );Then give us some table data - not 100's of records - just enough in the form
    INSERT INTO Table1 VALUES(Field1, Field2.... FieldN);
    ..Please post EXPLAIN PLAN - again with tags.
    HTH,
    Paul...
    /best regards, Håkan

  • Tables in subquery resulting in full table scans

    Hi,
    This is related to a p1 bug 13009447. Customer recently upgraded to 10G. Customer reported this type of problem for the second time.
    Problem Description:
    All the tables in sub-query are resulting in full table scans and hence are executing for hours.
    Here is the query
    SELECT /*+ PARALLEL*/
    act.assignment_action_id
    , act.assignment_id
    , act.tax_unit_id
    , as1.person_id
    , as1.effective_start_date
    , as1.primary_flag
    FROM pay_payroll_actions pa1
    , pay_population_ranges pop
    , per_periods_of_service pos
    , per_all_assignments_f as1
    , pay_assignment_actions act
    , pay_payroll_actions pa2
    , pay_action_classifications pcl
    , per_all_assignments_f as2
    WHERE pa1.payroll_action_id = :b2
    AND pa2.payroll_id = pa1.payroll_id
    AND pa2.effective_date
    BETWEEN pa1.start_date
    AND pa1.effective_date
    AND act.payroll_action_id = pa2.payroll_action_id
    AND act.action_status IN ('C', 'S')
    AND pcl.classification_name = :b3
    AND pa2.consolidation_set_id = pa1.consolidation_set_id
    AND pa2.action_type = pcl.action_type
    AND nvl (pa2.future_process_mode, 'Y') = 'Y'
    AND as1.assignment_id = act.assignment_id
    AND pa1.effective_date
    BETWEEN as1.effective_start_date
    AND as1.effective_end_date
    AND as2.assignment_id = act.assignment_id
    AND pa2.effective_date
    BETWEEN as2.effective_start_date
    AND as2.effective_end_date
    AND as2.payroll_id = as1.payroll_id
    AND pos.period_of_service_id = as1.period_of_service_id
    AND pop.payroll_action_id = :b2
    AND pop.chunk_number = :b1
    AND pos.person_id = pop.person_id
    AND (
    as1.payroll_id = pa1.payroll_id
    OR pa1.payroll_id IS NULL
    AND NOT EXISTS
    SELECT /*+ PARALLEL*/ NULL
    FROM pay_assignment_actions ac2
    , pay_payroll_actions pa3
    , pay_action_interlocks int
    WHERE int.locked_action_id = act.assignment_action_id
    AND ac2.assignment_action_id = int.locking_action_id
    AND pa3.payroll_action_id = ac2.payroll_action_id
    AND pa3.action_type IN ('P', 'U')
    AND NOT EXISTS
    SELECT /*+ PARALLEL*/
    NULL
    FROM per_all_assignments_f as3
    , pay_assignment_actions ac3
    WHERE :b4 = 'N'
    AND ac3.payroll_action_id = pa2.payroll_action_id
    AND ac3.action_status NOT IN ('C', 'S')
    AND as3.assignment_id = ac3.assignment_id
    AND pa2.effective_date
    BETWEEN as3.effective_start_date
    AND as3.effective_end_date
    AND as3.person_id = as2.person_id
    ORDER BY as1.person_id
    , as1.primary_flag DESC
    , as1.effective_start_date
    , act.assignment_id
    FOR UPDATE OF as1.assignment_id
    , pos.period_of_service_id
    Here is the execution plan for this query. We tried adding hints in sub-query to force indexes to pick-up but it is still doing Full table scans.
    Suspecting some db parameter which is causing this issue.
    In the
    - Full table scans on tables in the first sub-query
    PAY_PAYROLL_ACTIONS, PAY_ASSIGNMENT_ACTIONS, PAY_ACTION_INTERLOCKS
    - Full table scans on tables in Second sub-query
    PER_ALL_ASSIGNMENTS_F PAY_ASSIGNMENT_ACTIONS
    call count cpu elapsed disk query current rows
    Parse 1 0.00 0.00 0 0 0 0
    Execute 29 398.80 2192.99 238706 4991924 2383 0
    Fetch 1136 378.38 1921.39 0 4820511 0 1108
    total 1166 777.19 4114.38 238706 9812435 2383 1108
    Misses in library cache during parse: 1
    Misses in library cache during execute: 1
    Optimizer mode: ALL_ROWS
    Parsing user id: 41 (APPS) (recursive depth: 1)
    Rows Execution Plan
    0 SELECT STATEMENT MODE: ALL_ROWS
    0 FOR UPDATE
    0 PX COORDINATOR
    0 PX SEND (QC (ORDER)) OF ':TQ10009' [:Q1009]
    0 SORT (ORDER BY) [:Q1009]
    0 PX RECEIVE [:Q1009]
    0 PX SEND (RANGE) OF ':TQ10008' [:Q1008]
    0 HASH JOIN (ANTI BUFFERED) [:Q1008]
    0 PX RECEIVE [:Q1008]
    0 PX SEND (HASH) OF ':TQ10006' [:Q1006]
    0 BUFFER (SORT) [:Q1006]
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PER_ALL_ASSIGNMENTS_F' (TABLE) [:Q1006]
    0 NESTED LOOPS [:Q1006]
    0 NESTED LOOPS [:Q1006]
    0 NESTED LOOPS [:Q1006]
    0 HASH JOIN (ANTI) [:Q1006]
    0 BUFFER (SORT) [:Q1006]
    0 PX RECEIVE [:Q1006]
    0 PX SEND (HASH) OF ':TQ10002'
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PAY_ASSIGNMENT_ACTIONS' (TABLE)
    0 NESTED LOOPS
    0 NESTED LOOPS
    0 NESTED LOOPS
    0 NESTED LOOPS
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PAY_PAYROLL_ACTIONS' (TABLE)
    0 INDEX MODE: ANALYZED (UNIQUE SCAN) OF 'PAY_PAYROLL_ACTIONS_PK' (INDEX (UNIQUE)
    0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'PAY_POPULATION_RANGES_N4' (INDEX)
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PER_PERIODS_OF_SERVICE' (TABLE)
    0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'PER_PERIODS_OF_SERVICE_N3' (INDEX)
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PER_ALL_ASSIGNMENTS_F' (TABLE)
    0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'PER_ASSIGNMENTS_N4' (INDEX)
    0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'PAY_ASSIGNMENT_ACTIONS_N51' (INDEX)
    0 PX RECEIVE [:Q1006]
    0 PX SEND (HASH) OF ':TQ10005' [:Q1005]
    0 VIEW OF 'VW_SQ_1' (VIEW) [:Q1005]
    0 HASH JOIN [:Q1005]
    0 BUFFER (SORT) [:Q1005]
    0 PX RECEIVE [:Q1005]
    0 PX SEND (BROADCAST) OF ':TQ10000'
    0 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PAY_PAYROLL_ACTIONS' (TABLE)
    0 HASH JOIN [:Q1005]
    0 PX RECEIVE [:Q1005]
    0 PX SEND (HASH) OF ':TQ10004' [:Q1004]
    0 PX BLOCK (ITERATOR) [:Q1004]
    0 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PAY_ASSIGNMENT_ACTIONS' (TABLE) [:Q1004]
    0 BUFFER (SORT) [:Q1005]
    0 PX RECEIVE [:Q1005]
    0 PX SEND (HASH) OF ':TQ10001'
    0 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PAY_ACTION_INTERLOCKS' (TABLE)
    0 TABLE ACCESS MODE: ANALYZED (BY INDEX ROWID) OF 'PAY_PAYROLL_ACTIONS' (TABLE) [:Q1006]
    0 INDEX MODE: ANALYZED (UNIQUE SCAN) OF 'PAY_PAYROLL_ACTIONS_PK' (INDEX (UNIQUE)) [:Q1006]
    0 INDEX MODE: ANALYZED (UNIQUE SCAN) OF 'PAY_ACTION_CLASSIFICATIONS_PK' (INDEX (UNIQUE))[:Q1006]
    0 INDEX MODE: ANALYZED (RANGE SCAN) OF 'PER_ASSIGNMENTS_F_PK' (INDEX (UNIQUE)) [:Q1006]
    0 PX RECEIVE [:Q1008]
    0 PX SEND (HASH) OF ':TQ10007' [:Q1007]
    0 VIEW OF 'VW_SQ_2' (VIEW) [:Q1007]
    0 FILTER [:Q1007]
    0 HASH JOIN [:Q1007]
    0 BUFFER (SORT) [:Q1007]
    0 PX RECEIVE [:Q1007]
    0 PX SEND (BROADCAST) OF ':TQ10003'
    0 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PER_ALL_ASSIGNMENTS_F' (TABLE)
    0 PX BLOCK (ITERATOR) [:Q1007]
    0 TABLE ACCESS MODE: ANALYZED (FULL) OF 'PAY_ASSIGNMENT_ACTIONS' (TABLE) [:Q1007]
    Elapsed times include waiting on following events:
    Event waited on Times Max. Wait Total Waited
    ---------------------------------------- Waited ---------- ------------
    enq: KO - fast object checkpoint 32 0.02 0.12
    os thread startup 8 0.02 0.19
    PX Deq: Join ACK 198 0.00 0.04
    PX Deq Credit: send blkd 167116 1.95 1103.72
    PX Deq Credit: need buffer 327389 1.95 266.30
    PX Deq: Parse Reply 148 0.01 0.03
    PX Deq: Execute Reply 11531 1.95 1901.50
    PX qref latch 23060 0.00 0.60
    db file sequential read 108199 0.17 22.11
    db file scattered read 9272 0.19 51.74
    PX Deq: Table Q qref 78 0.00 0.03
    PX Deq: Signal ACK 1165 0.10 10.84
    enq: PS - contention 73 0.00 0.00
    reliable message 27 0.00 0.00
    latch free 218 0.00 0.01
    latch: session allocation 11 0.00 0.00
    Thanks in advance
    Suresh PV

    Hi,
    welcome,
    how is the query performing if you delete all the hints for PARALLEL, because most of the waits are related to waits on Parallel.
    Herald ten Dam
    http://htendam.wordpress.com
    PS. Use "{code}" for showing your code and explain plans, it looks nicer

  • SIDs for Full table scan wait events in db

    Guys,
    10.2.0.5/ 2 node RAC / RHEL-3
    CanAnyone provide me an sql to find all SID doing full table scans in a db?
    Thanks!
    Hari

    You ought to be able to query v$sql_plan for those sql plans with a full scan in them and if you want all the recent plans that contain a full table scan in them. You can join this back to v$session for those session currently executing a full table scan but if the sql in question was a previous statement executed by the session the join will not show the session because that statement is no longer the current statement.
    1 select p.sql_id, s.sid, p.object_name, p.operation, p.options
    2 from v$sql_plan p, v$session s
    3 where p.options like '%FULL%'
    4* and s.sql_id = p.sql_id
    You will probably want to filter out internal operations (operation = "FIXED TABLE")
    HTH -- Mark D Powell --

  • Why does not  a query go by index but FULL TABLE SCAN

    I have two tables;
    table 1 has 1400 rwos and more than 30 columns , one of them is named as 'site_code' , a index was created on this column;
    table 2 has more 150 rows than 20 column , this primary key is 'site_code' also.
    the two tables were analysed by dbms_stats.gather_table()...
    when I run the explain for the 2 sqls below:
    select * from table1 where site_code='XXXXXXXXXX';
    select * from table1 where site_code='XXXXXXXXXX';
    certainly the oracle explain report show that 'Index scan'
    but the problem raised that
    I try to explain the sql
    select *
    from table1,table2
    where 1.'site_code'=2.'site_code'
    the explain report that :
    select .....
    FULL Table1 Scan
    FULL Table2 Scan
    why......

    Nikolay Ivankin  wrote:
    BluShadow wrote:
    Nikolay Ivankin  wrote:
    Try to use hint, but I really doubt it will be faster.No, using hints should only be advised when investigating an issue, not recommended for production code, as it assumes that, as a developer, you know better than the Oracle Optimizer how the data is distributed in the data files, and how the data is going to grow and change over time, and how best to access that data for performance etc.Yes, you are absolutly right. But aren't we performing such an investigation, are we? ;-)The way you wrote it, made it sound that a hint would be the solution, not just something for investigation.
    select * from .. always performs full scan, so limit your query.No, select * will not always perform a full scan, that's just selecting all the columns.
    A select without a where clause or that has a where clause that has low selectivity will result in full table scans.But this is what I have ment.But not what you said.

  • Finding the Text of SQL Query causing Full Table Scans

    Hi,
    does anyone have a sql script, that shows the complete sql text of queries that have caused a full table scan?
    Please also let me know as to how soon this script needs to be run, in the sense does it work only while the query is running or would it work once it completes (if so is there a valid duration, such as until next restart, etc.)
    Your help is appreciated.
    Thx,
    Mayuran

    Finding the Text of SQL Query Causing Full Table Scan

Maybe you are looking for