How to use index when use analytic functions?
Oracle 11gR2, I have a an indexed snapshot log table (sequence$$ and PK indexed), and I use a query to access it...
query looks like:
SELECT "M_ROW$$", "SNAPTIME$$", "DMLTYPE$$", "OLD_NEW$$", "CHANGE_VECTOR$$", "SEQUENCE$$", "ID", "SITEID", "WEBPAGEID", "WEBFOLDERID"
FROM mlog$_table1
WHERE dmltype$$ = 'D'
AND sequence$$ IN
(SELECT DISTINCT
LAST_VALUE (sequence$$)
OVER (PARTITION BY siteid ORDER BY siteid)
FROM mlog$_table1);
how could I access mlog$_table1
explain plan looks like:
Plan
SELECT STATEMENT ALL_ROWSCost: 53 Bytes: 605.864 Cardinality: 1.736
6 HASH JOIN Cost: 53 Bytes: 605.864 Cardinality: 1.736
4 VIEW VIEW SYS.VW_NSO_1 Cost: 28 Bytes: 22.555 Cardinality: 1.735
3 HASH UNIQUE Cost: 28 Bytes: 45.110 Cardinality: 1.735
2 WINDOW SORT Cost: 28 Bytes: 45.110 Cardinality: 1.735
1 TABLE ACCESS FULL TABLE BONGO.MLOG$_PDSI1 Cost: 25 Bytes: 45.110 Cardinality: 1.735
5 TABLE ACCESS FULL TABLE BONGO.MLOG$_PDSI1 Cost: 25 Bytes: 582.960 Cardinality: 1.735
ok, I think I feel like a newbie :)
explain plan for your query is:
Plan
SELECT STATEMENT ALL_ROWSCost: 22,1 Bytes: 416,678 Cardinality: 2,654
2 SORT GROUP BY Cost: 22,1 Bytes: 416,678 Cardinality: 2,654
1 TABLE ACCESS FULL TABLE IBIS.MLOG$_PARTIJA Cost: 22,098 Bytes: 416,678 Cardinality: 2,654
but it runs for about 3-4 sec..
1st query:
create or replace view x as
select * from mlog$_partija v
where not (DMLTYPE$$='D' and update_type=2)
and sequence$$=(select max(sequence$$) from mlog$_partija t
where t.par_sifpar=v.par_sifpar);
runs about 17 sec...
wich is expected since there's a max in subselect...
but, it's explain plan is:
Plan
SELECT STATEMENT ALL_ROWSCost: 108,957 Bytes: 1,84 Cardinality: 1
5 HASH JOIN Cost: 108,957 Bytes: 1,84 Cardinality: 1
3 VIEW VIEW SYS.VW_SQ_1 Cost: 22,564 Bytes: 68.634.228 Cardinality: 2.639.778
2 HASH GROUP BY Cost: 22,564 Bytes: 68.634.228 Cardinality: 2.639.778
1 TABLE ACCESS FULL TABLE IBIS.MLOG$_PARTIJA Cost: 22,05 Bytes: 68.634.228 Cardinality: 2.639.778
4 TABLE ACCESS FULL TABLE IBIS.MLOG$_PARTIJA Cost: 22,145 Bytes: 4.788.557.292 Cardinality: 2.639.778
but, I made a third solution wich is something like:
create table mlog_table1_last as
select siteid, max(sequence$$) max_seq from mlog$_table1 group by siteid
I run a query on that temp table:
select * from mlog$_table1 v
where not (DMLTYPE$$='D' and update_type=2)
and sequence$$=(select max_seq from mlog_table1_last t
where t.siteid=v.siteid);
it's explain plan is bad:
Plan
SELECT STATEMENT ALL_ROWSCost: 2.588.886 Bytes: 1,814 Cardinality: 1
3 FILTER
1 TABLE ACCESS FULL TABLE IBIS.MLOG$_PARTIJA Cost: 22,148 Bytes: 4.788.557.292 Cardinality: 2.639.778
2 INDEX RANGE SCAN INDEX IBIS.MLOG_PARIJA_LAST_NDX2 Cost: 1 Bytes: 111,02 Cardinality: 4,27
but it runs for 1-2 sec..
why?
Similar Messages
-
Using indexes when using group by clause
How can I make use of indexes when there is a group by clause in the sql/ pl/sql. Heard that when ever there is a group by clause , sql bypasses use of indexes. Is it true?
Thanks in advanceHi,
Depending on the query containing the group by, indexes will still be used.
For example, create a big table based on the all_objects table. Then create an index on the object_type column. Then run this query:
select count(*), object_type from big_table where object_type != 'PACKAGE' group by object_type
The execution plan for this query will show the index to be used, the group by does not prevent the optimizer from using an index. Then run this query:
select count(*), object_type from big_table group by object_type
The execution plan for this query will show the index not to be used because the whole table - no restrictions - needs to be read to get the result.
Hope this helps!
Regards,
Marco Stuijvenberg
=
www.marcostuijvenberg.nl -
Query not using index when using 'or' clause
I have a problem with something I can't understand about indexes in Oracle 11g.
We can create test data with:
create table test2(field1 varchar2(100),field2 varchar2(100),field3 number,field4 varchar2(100));
create index test2_idx1 on test2(upper(field1));
create index test2_idx1b on test2(field1);
create index test2_idx2 on test2(field3);
DECLARE
j NUMBER :=1;
BEGIN
FOR i IN 1..500000
LOOP
INSERT
INTO test2
(field1,field2, field3, field4)
VALUES
('field1='||i,'a', j, 'i' );
IF (i mod 1000)=0 THEN
j := j+1;
END IF;
END LOOP;
COMMIT;
END;
EXEC DBMS_STATS.GATHER_TABLE_STATS ('system', 'test2');
Then I make some explain plans which result I can't understand
Query 1:
SELECT * FROM test2 WHERE field3=1;
Explain plan:
Explain plan for query 01
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1003 | 28084 | 10 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
Everything OK here. Index is used.
Query 2:
SELECT * FROM test2 WHERE upper(field1)='FIELD1=1';
Explain plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 28 | 4 (0)| 00:00:01 |
| 1 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 28 | 4 (0)| 00:00:01 |
|* 2 | INDEX RANGE SCAN | TEST2_IDX1 | 1 | | 3 (0)| 00:00:01 |
Everything OK again. Index is used.
Query 3:
SELECT /*+ USE_CONCAT */ * FROM test2 WHERE field1='FIELD1=1' OR field3=1;
Explain plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1004 | 28112 | 14 (0)| 00:00:01 |
| 1 | CONCATENATION | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 28 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TEST2_IDX1B | 1 | | 3 (0)| 00:00:01 |
|* 4 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
Indenxes are used in concatenation. No problem again.
Query 4:
SELECT /*+ USE_CONCAT */ * FROM test2 WHERE upper(field1)='FIELD1=1' OR field3=1;
Explain plan
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1004 | 28112 | 641 (4)| 00:00:08 |
| 1 | CONCATENATION | | | | | |
|* 2 | TABLE ACCESS FULL | TEST2 | 1 | 28 | 631 (4)| 00:00:08 |
|* 3 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1003 | 28084 | 10 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | TEST2_IDX2 | 1003 | | 5 (0)| 00:00:01 |
Here my problem arises. Why is test2_idx1 not being used? Is it because it is a function index? Is there any workaround in this cases?
Thanks a lot in advance.Interesting. A "workaround" which I thought first was:
SELECT /*+ USE_CONCAT */ * FROM test2 WHERE upper(field1)='FIELD1=1'
UNION ALL
SELECT /*+ USE_CONCAT */ * FROM test2 WHERE field3=1;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1001 | 28042 | 15 (74)| 00:00:01 |
| 1 | UNION-ALL | | | | | |
| 2 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 42 | 4 (0)| 00:00:01 |
|* 3 | INDEX RANGE SCAN | TEST2_IDX1 | 1 | | 3 (0)| 00:00:01 |
| 4 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1000 | 28000 | 11 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | TEST2_IDX2 | 1000 | | 5 (0)| 00:00:01 |
------------------------------------------------------------------------------------------- But I do not like using UNION for such tricks. So I thought, what would ORACLE do without hint?
SELECT * FROM test2 WHERE upper(field1)='FIELD1=1' or field3=1;
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1001 | 42042 | 176 (0)| 00:00:03 |
| 1 | TABLE ACCESS BY INDEX ROWID | TEST2 | 1001 | 42042 | 176 (0)| 00:00:03 |
| 2 | BITMAP CONVERSION TO ROWIDS | | | | | |
| 3 | BITMAP OR | | | | | |
| 4 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 5 | INDEX RANGE SCAN | TEST2_IDX2 | | | 5 (0)| 00:00:01 |
| 6 | BITMAP CONVERSION FROM ROWIDS| | | | | |
|* 7 | INDEX RANGE SCAN | TEST2_IDX1 | | | 3 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------- Thist looks perfect to me. (Please ignore the "higher" cost on the second plan. On your real data, it should be faster. Is it?) -
Hi everyone,
Kindly advice how to retrieve character '#' when use Shift key + 3 instead of Option key + 3.
Thank you in advance.Hi Tom,
Thanks for your proposed solution. The problem has been solved. -
Question about using email when using computer at internet cafe
I am confused about using email when using my computer at an internet cafe.
Of course - I use the internet cafe's wifi connection/network.
How does this effect my email?
what do I have to do to use my email when logged on at an internet cafe?zxcvbnm1 wrote:
I am confused about using email when using my computer at an internet cafe.
Of course - I use the internet cafe's wifi connection/network.
How does this effect my email?
what do I have to do to use my email when logged on at an internet cafe?
You don't give enough information to do more than discuss the issue in general terms.
You should be able to read your email wherever you can get an internet connection.
To send email, it depends on the email provider you are using. Gmail and other web based mail should not have any issues. However, if you are attempting to use an account that uses your ISP's mail servers, you will probably not be able to send mail. You may want to check with your ISP in that case, to see if they offer webmail.
Hope this may have answered your question. -
Is there a known issue for using IE11 when using business catalyst cms
Is there a known issue for using IE11 when using business catalyst cms? I have a client trying to update pages on her site using IE11 and the it says it updates successfully, but the new content is not saved.
I concur with Barry; I see no significant difference in using the Home button vs. the gestures. But the "fade" effect is part of iOS 7.1 and there's no way to disable it that I know of.
Regards. -
How to use group by in analytic function
I need to write department which has minimum salary in one row. It must be with analytic function but i have problem with group by. I can not use min() without group by.
select * from (select min(sal) min_salary, deptno, RANK() OVER (ORDER BY sal ASC, rownum ASC) RN from emp group by deptno) WHERE RN < 20 order by deptno;
Edited by: senza on 6.11.2009 16:09different query, different results.
LPALANI@l11gr2>select department_id, min(salary)
2 from hr.employees
3 group by department_id
4 order by 2;
DEPARTMENT_ID MIN(SALARY)
50 2,100
20 2,100
30 2,500
60 4,200
10 4,400
80 6,100
40 6,500
100 6,900
7,000
110 8,300
70 10,000
90 17,000
12 rows selected.
LPALANI@l11gr2>
LPALANI@l11gr2>-- Always lists one department in a non-deterministic way
LPALANI@l11gr2>select * from (
2 select department_id, min(salary) min_salary
3 from hr.employees
4 group by department_id
5 order by 2) where rownum = 1;
DEPARTMENT_ID MIN_SALARY
20 2,100
LPALANI@l11gr2>
LPALANI@l11gr2>-- Out of the departments with the same least salary, returns the one with the least department number
LPALANI@l11gr2>SELECT MIN (department_id) KEEP (DENSE_RANK FIRST ORDER BY salary) AS dept_with_lowest_sal, min(salary) min_salary
2 FROM hr.employees;
DEPT_WITH_LOWEST_SAL MIN_SALARY
20 2,100
LPALANI@l11gr2>
LPALANI@l11gr2>-- This will list all the deparments with the minimum salary
LPALANI@l11gr2>select department_id, min_salary
2 from (select
3 department_id,
4 min(salary) min_salary,
5 RANK() OVER (ORDER BY min(salary) ASC) RN
6 from hr.employees
7 group by department_id)
8 WHERE rn=1;
DEPARTMENT_ID MIN_SALARY
20 2,100
50 2,100 -
How to use index, when query has decode/case
Hi,
I have the following query
i have a index on party_id,party_type_Code in the zx_party_tax_profile table But this index is not used as Iam using a decode on the columns of the zx_party_tax_profile table,
Is there any way i can rewrite the query so that it uses index
sELECT /*+ INDEX(ZX_PARTY_TAX_PROFILE_U2) */ party_tax_profile_id FROM (SELECT
ThirdPartyTaxProfileEO.SUPPLIER_FLAG,
ThirdPartyTaxProfileEO.CUSTOMER_FLAG,
ThirdPartyTaxProfileEO.SITE_FLAG,
ThirdPartyTaxProfileEO.PARTY_TAX_PROFILE_ID,
ThirdPartyTaxProfileEO.PARTY_ID,
ThirdPartyTaxProfileEO.REP_REGISTRATION_NUMBER,
ThirdPartyTaxProfileEO.OBJECT_VERSION_NUMBER,
ThirdPartyTaxProfileEO.REGISTRATION_TYPE_CODE,
ThirdPartyTaxProfileEO.COUNTRY_CODE,
ThirdPartyTaxProfileEO.MERGED_TO_PTP_ID,
ThirdPartyTaxProfileEO.MERGED_STATUS_CODE,
ThirdPartyTaxProfileEO.PROGRAM_APP_NAME,
ThirdPartyTaxProfileEO.PROGRAM_NAME,
PartyPEO.PARTY_NAME,
PartyPEO.PARTY_ID AS PARTY_ID1,
PartyPEO.PARTY_NUMBER,
decode(ThirdPartyTaxProfileEO.CUSTOMER_FLAG,
'Y',decode(ThirdPartyTaxProfileEO.SUPPLIER_FLAG,
'Y', 'SC',
'C'),
decode(ThirdPartyTaxProfileEO.SUPPLIER_FLAG,
'Y', 'S',
NULL)
) AS PARTY_USAGE,
ThirdPartyTaxProfileEO.REP_REGISTRATION_NUMBER AS TAX_REG_NUMBER,
LkupPartyUsage.MEANING AS PARTY_USAGE_DESC,
PartyPEO.PARTY_NAME AS PARTY_FULL_NAME,
PartyPEO.ADDRESS1||','||
PartyPEO.ADDRESS2||','||
PartyPEO.ADDRESS3||','||
PartyPEO.CITY||','||
PartyPEO.postal_code||','||
PartyPEO.COUNTRY AS ADDRESS,
PartyPEO.COUNTRY AS COUNTRY_CODE_TCA,
TerritoryPEO.TERRITORY_SHORT_NAME AS COUNTRY_NAME,
PartyPEO.JGZZ_FISCAL_CODE AS TAX_PAYER_ID,
PartyPEO.DUNS_NUMBER_C AS DUNS_NUMBER,
PartyPEO.Party_Number as Party_Num_Calc,
null as REGISTRATION_TYPE_NAME,
null as ROUNDING_LEVEL_NAME,
null as ROUNDING_RULE_NAME,
null as COUNTRY_NAME_PTP,
'ZX_PARTY_TAX_PROFILE' as TAX_REPORTING_ENTITY_CODE
FROM ZX_PARTY_TAX_PROFILE ThirdPartyTaxProfileEO,
HZ_PARTIES PartyPEO,
FND_LOOKUP_VALUES_VL LkupPartyUsage,
FND_TERRITORIES_VL TerritoryPEO
WHERE ThirdPartyTaxProfileEO.PARTY_ID = PartyPEO.PARTY_ID AND
LkupPartyUsage.LOOKUP_CODE = decode(ThirdPartyTaxProfileEO.CUSTOMER_FLAG,
'Y',decode(ThirdPartyTaxProfileEO.SUPPLIER_FLAG,
'Y', 'SC',
'C'),
decode(ThirdPartyTaxProfileEO.SUPPLIER_FLAG,
'Y', 'S',
NULL)
) AND
PartyPEO.COUNTRY = TerritoryPEO.Territory_Code (+) AND
LkupPartyUsage.LOOKUP_TYPE = 'ZX_TP_PARTY_USAGE'
ORDER BY UPPER(PARTY_FULL_NAME)) QRSLT WHERE UPPER(PARTY_NAME) IS NOT
NULL
Any help will be appreciatedYou can rewrite your where clause to not use decode or case statements e.g. this:
AND LkupPartyUsage.LOOKUP_CODE = DECODE( ThirdPartyTaxProfileEO.CUSTOMER_FLAG
, 'Y', DECODE( ThirdPartyTaxProfileEO.SUPPLIER_FLAG, 'Y', 'SC', 'C' )
, DECODE( ThirdPartyTaxProfileEO.SUPPLIER_FLAG, 'Y', 'S', NULL ) )
)can be rewritten to this:
and (
( ThirdPartyTaxProfileEO.CUSTOMER_FLAG = 'Y' AND
((ThirdPartyTaxProfileEO.SUPPLIER_FLAG = 'Y' AND LkupPartyUsage.LOOKUP_CODE = 'SC') or
ThirdPartyTaxProfileEO.SUPPLIER_FLAG != 'Y' AND LkupPartyUsage.LOOKUP_CODE = 'C')) or
( ThirdPartyTaxProfileEO.CUSTOMER_FLAG != 'Y' AND
((ThirdPartyTaxProfileEO.SUPPLIER_FLAG = 'Y' AND LkupPartyUsage.LOOKUP_CODE = 'S') or
ThirdPartyTaxProfileEO.SUPPLIER_FLAG != 'Y' AND LkupPartyUsage.LOOKUP_CODE is null))
)It's not as sussinct, but it avoids the use of functions that could be preventing the optimiser from using an index. -
Problem with table-indexes when using select-options in select
Hello experts,
is it right that table-indexes will not be used if you take select-options to select data from the database?
in detail:
i have build up an table-index for one of our db-tables and test it via an test-programm. The first test with '=' comparisons worked fine. Every key of the index was used; checked via ST05!
e.g.: SELECT * FROM TABLEA INTO ITAB WHERE keya = '1' AND keyb = '2' AND keyc = '3'.
Now i startet the test with select-options
e.g.: SELECT * FROM TABLEA INTO ITAB WHERE keya IN seltabA AND keyb IN seltabB AND keyc IN seltabC.
First of all i just filled the seltabs with only 1 value: eg: seltabA= SIGN = 'I' OPTION = 'EQ' LOW = '1' etc.
Everything worked fine. Every key of the index was used.
But now, I putted more than one entries in the seltabs e.g.
seltabA: SIGN = 'I' OPTION = 'EQ' LOW = '1'
SIGN = 'I' OPTION = 'EQ' LOW = '2'
SIGN = 'I' OPTION = 'EQ' LOW = '3'
From now on, the indexed was not used completely (with all keys).
Isn't that strange? How can i use select-options or sel-ranges with using the complete table-indexes?
Thanks a lot,
MarcelHi Hermann,
i hope this helps:
this is the first one, which uses the complete index:
SELECT
"KOWID" , "LIFNR" , "KLPOS" , "ORGID" , "KOART" , "MATNR" , "GLTVON" ,
"GLTBIS" , "WERT" , "ABLIF" , "FAKIV" , "AENAM" , "AEDAT" , "AFORM" ,
"HERSTELLER" , "ARTGRP" , "OE_FREITXT" , "ARTFREITEXT" , "STATUS" ,
"TERDAT"
FROM
"/dbcon/01_con"
WHERE
"MANDT" = ? AND "LIFNR" = ? AND "ORGID" = ? AND "KOART_BASIS" = ? AND
"STATUS" = ? AND "GEWAEHR_KOWID" < ? AND ( "STATUS" = ? OR "STATUS" = ? OR
"STATUS" = ? ) WITH UR
RESULT: 5 IXSCAN /dbcon/01_con05 #key columns: 4
And the second one, which does not use the complete index! The 3 ranges are filled each with 2 values. Remember; when i fill them each with only one value, the result is the same as you can see above(/dbcon/01_con05 #key columns: 4):
SELECT
"KOWID" , "LIFNR" , "KLPOS" , "ORGID" , "KOART" , "MATNR" , "GLTVON" ,
"GLTBIS" , "WERT" , "ABLIF" , "FAKIV" , "AENAM" , "AEDAT" , "AFORM" ,
"HERSTELLER" , "ARTGRP" , "OE_FREITXT" , "ARTFREITEXT" , "STATUS" ,
"TERDAT"
FROM
"/dbcon/01_con"
WHERE
"MANDT" = ? AND "LIFNR" IN ( ? , ? ) AND "ORGID" IN ( ? , ? ) AND
"KOART_BASIS" IN ( ? , ? ) AND "GEWAEHR_KOWID" < ? AND ( "STATUS" = ? OR
"STATUS" = ? OR "STATUS" = ? ) WITH UR
and here the access-plan
0 SELECT STATEMENT ( Estimated Costs = 5,139E+01 [timerons] )
5 1 RETURN
5 2 NLJOIN
5 3 [O] TBSCAN
5 4 SORT
5 TBSCAN GENROW
5 6 <i> FETCH /dbcon/01_con
7 IXSCAN /dbcon/01_con05 #key columns: 2
As you can see, only 2 keys were taken for indexed selection!
Any idea?
Kind regards,
MArcel
Edited by: Marcel Ebert on Jul 28, 2009 5:25 PM -
Understanding row_number() and using it in an analytic function
Dear all;
I have been playing around with row_number and trying to understand how to use it and yet I still cant figure it out...
I have the following code below
create table Employee(
ID VARCHAR2(4 BYTE) NOT NULL,
First_Name VARCHAR2(10 BYTE),
Last_Name VARCHAR2(10 BYTE),
Start_Date DATE,
End_Date DATE,
Salary Number(8,2),
City VARCHAR2(10 BYTE),
Description VARCHAR2(15 BYTE)
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values ('01','Jason', 'Martin', to_date('19960725','YYYYMMDD'), to_date('20060725','YYYYMMDD'), 1234.56, 'Toronto', 'Programmer');
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('02','Alison', 'Mathews', to_date('19760321','YYYYMMDD'), to_date('19860221','YYYYMMDD'), 6661.78, 'Vancouver','Tester')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('03','James', 'Smith', to_date('19781212','YYYYMMDD'), to_date('19900315','YYYYMMDD'), 6544.78, 'Vancouver','Tester')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('04','Celia', 'Rice', to_date('19821024','YYYYMMDD'), to_date('19990421','YYYYMMDD'), 2344.78, 'Vancouver','Manager')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('05','Robert', 'Black', to_date('19840115','YYYYMMDD'), to_date('19980808','YYYYMMDD'), 2334.78, 'Vancouver','Tester')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('06','Linda', 'Green', to_date('19870730','YYYYMMDD'), to_date('19960104','YYYYMMDD'), 4322.78,'New York', 'Tester')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('07','David', 'Larry', to_date('19901231','YYYYMMDD'), to_date('19980212','YYYYMMDD'), 7897.78,'New York', 'Manager')
insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
values('08','James', 'Cat', to_date('19960917','YYYYMMDD'), to_date('20020415','YYYYMMDD'), 1232.78,'Vancouver', 'Tester')I did a simple select statement
select * from Employee e
and it returns this below
ID FIRST_NAME LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPTION
01 Jason Martin 25-JUL-96 25-JUL-06 1234.56 Toronto Programmer
02 Alison Mathews 21-MAR-76 21-FEB-86 6661.78 Vancouver Tester
03 James Smith 12-DEC-78 15-MAR-90 6544.78 Vancouver Tester
04 Celia Rice 24-OCT-82 21-APR-99 2344.78 Vancouver Manager
05 Robert Black 15-JAN-84 08-AUG-98 2334.78 Vancouver Tester
06 Linda Green 30-JUL-87 04-JAN-96 4322.78 New York Tester
07 David Larry 31-DEC-90 12-FEB-98 7897.78 New York Manager
08 James Cat 17-SEP-96 15-APR-02 1232.78 Vancouver TesterI wrote another select statement with row_number. see below
SELECT first_name, last_name, salary, city, description, id,
ROW_NUMBER() OVER(PARTITION BY description ORDER BY city desc) "Test#"
FROM employee
and I get this result
First_name last_name Salary City Description ID Test#
Celina Rice 2344.78 Vancouver Manager 04 1
David Larry 7897.78 New York Manager 07 2
Jason Martin 1234.56 Toronto Programmer 01 1
Alison Mathews 6661.78 Vancouver Tester 02 1
James Cat 1232.78 Vancouver Tester 08 2
Robert Black 2334.78 Vancouver Tester 05 3
James Smith 6544.78 Vancouver Tester 03 4
Linda Green 4322.78 New York Tester 06 5
I understand the partition by which means basically for each associated group a unique number wiill be assigned for that row, so in this case since tester is one group, manager is another group, and programmer is another group then tester gets its own unique number for each row, manager as well and etc.What is throwing me off is the order by and how this numbering are assigned. why is
1 assigned to Alison Mathews for the tester group and 2 assigned to James Cat and 3 assigned Robert Black
I apologize if this is a stupid question, i have tried reading about it online and looking at the oracle documentation but that still dont fully understand why.user13328581 wrote:
understanding row_number() and using it in an analytic functionROW_NUMBER () IS an analytic fucntion. Are you trying to use the results of ROW_NUMBER in another analytic function? If so, you need a sub-query. Analuytic functions can't be nested within other analytic functions.
...I have the following code below
... I did a simple select statementThanks for posting all that! It's really helpful.
... and I get this result
First_name last_name Salary City Description ID Test#
Celina Rice 2344.78 Vancouver Manager 04 1
David Larry 7897.78 New York Manager 07 2
Jason Martin 1234.56 Toronto Programmer 01 1
Alison Mathews 6661.78 Vancouver Tester 02 1
James Cat 1232.78 Vancouver Tester 08 2
Robert Black 2334.78 Vancouver Tester 05 3
James Smith 6544.78 Vancouver Tester 03 4
Linda Green 4322.78 New York Tester 06 5... What is throwing me off is the order by and how this numbering are assigned. why is
1 assigned to Alison Mathews for the tester group and 2 assigned to James Cat and 3 assigned Robert Black That's determined by the analytic ORDER BY clause. Yiou said "ORDER BY city desc", so a row where city='Vancouver' will get a lower namber than one where city='New York', since 'Vancouver' comes after 'New York' in alphabetic order.
If you have several rows that all have the same city, then you can be sure that ROW_NUMBER will assign them consecutive numbers, but it's arbitrary which one of them will be lowest and which highest. For example, you have 5 'Tester's: 4 from Vancouver and 1 from New York. There's no particular reason why the one with first_name='Alison' got assinge 1, and 'James' got #2. If you run the same query again, without changing the table at all, then 'Robert' might be #1. It's certain that the 4 Vancouver rows will be assigned numbers 1 through 4, but there's no way of telling which of those 4 rows will get which of those 4 numbers.
Similar to a query's ORDER BY clause, the analytic ORDER BY clause can have two or more expressions. The N-th one will only be considered if there was a tie for all (N-1) earlier ones. For example "ORDER BY city DESC, last_name, first_name" would mena 'Vancouver' comes before 'New York', but, if multiple rows all have city='Vancouver', last_name would determine the order: 'Black' would get a lower number than 'Cat'. If you had multiple rows with city='Vancouver' and last_name='Black', then the order would be determined by first_name. -
How do we delete apps from ipod 4 when using same account as iphone 4s, we can delete from the phone but not the ipod, and when i get an app on my phone it automatically comes up on the ipod and visa versa, now ipod is full,
Read the article from which the thread was posted, it clearly defines how to use multiple iDevices on a single computer.
Sharing an Apple ID is not an issue. -
Query don't use the right index when using bind variables
Hi people !
I need some help because I have an issue with a query that don t use the right Indexes as it should
First of all, I have mainly three tables :
ORDER : Table that contains description for each Order (approximately 1 000 000 Records)
ORDER_MVTS : Table that contains the tasks made (called movements) to set up each Orders
with quantity of packages prepared for each product (approximately 10 000 000 Records)
PRODUCT : Tables that contains the products (approximately 50 000 Records)
When I launch the query with hard coded values, it brings back response very fast
because it uses the right index (ORDER_DHR_VALID) which represent the date and hour of the order
(with format 'DD/MM/YYYY HH24:MI:SS'). The selectivity for this index is good.
NB 1: I have to use the trick " >= Trunc(date) and < trunc(date) +1 " to filter on a simple date because
the index contains hour and minutes (I know it wasn't probably a bright idea at conception time).
NB 2: The index on ORDER_MVTS.PRODUCT_CODE is'nt discriminating enough because there is'nt enough different products.
It's the same for index on CUSTOMER_CODE and on MVT_TYPE so only the index on ORDER.DHR_VALID is good.
Here is the correct explain plan when I execute the query with hard coded values :
SELECT SUM(ORDER_MVTS.NB_PACKAGE)
FROM ORDER_MVTS, PRODUCT, ORDER
WHERE ORDER.DHR_VALID >= TRUNC(to_date('14/11/2008 10:04:56','DD/MM/YYYY HH24:MI:SS'))
AND ORDER.DHR_VALID < TRUNC(to_date('14/11/2008 10:04:56','DD/MM/YYYY HH24:MI:SS')) + 1
AND ORDER_MVTS.MVT_TYPE = 'DELIVERY'
AND PRODUCT.CODE = ORDER_MVTS.PRODUCT_CODE
AND ORDER_MVTS.ORDER_CODE = ORDER.CODE
AND ORDER.CUSTOMER_CODE = 'ADIDAS'
AND PRODUCT.CODE = 1234
Rows Row Source Operation
1 SORT AGGREGATE
2 NESTED LOOPS
4 NESTED LOOPS
2 INDEX UNIQUE SCAN (object id 378548) --> PRODUCT_PK
4 TABLE ACCESS BY INDEX ROWID ORDER
777 INDEX RANGE SCAN (object id 378119) --> ORDER_DHR_VALID
2 TABLE ACCESS BY INDEX ROWID ORDER_MVTS
30 INDEX RANGE SCAN (object id 377784) --> ORDER_MVTS_ORDER_FK
Now the problem is when the query is used in a Cursor with bind variables.
It seems like Oracle don't use index on ORDER.DHR_VALID because he can't figure out that he have
to actually filter on a short period of time (only one day).
So Oracle uses the index on ORDER_MVTS.PRODUCT_CODE which is'nt a bright idea (it takes 10 secondes instead of just one)
Here is the bad explain plan :
Rows Row Source Operation
1 SORT AGGREGATE
2 NESTED LOOPS
722 NESTED LOOPS
2 INDEX UNIQUE SCAN (object id 378548) --> PRODUCT_PK
722 TABLE ACCESS BY INDEX ROWID ORDER_MVTS
1790 INDEX RANGE SCAN (object id 377777) --> ORDER_MVTS_PRODUCT_FK
2 TABLE ACCESS BY INDEX ROWID ORDER
1442 INDEX UNIQUE SCAN (object id 378439) --> ORDER_PK
Now I have found two solutions to this problem :
1) using a Hint to force the use of index on ORDER.DHR_VALID (with /*+ INDEX(ORDER ORDER_DHR_VALID) */ )
2) Using Dynamic SQL and keeping the date hard coded (but not the other values except mvt_type)
For example :
QUERY :=
'SELECT SUM(ORDER_MVTS.NB_PACKAGE)
FROM ORDER_MVTS, PRODUCT, ORDER
WHERE ORDER.DHR_VALID >= TRUNC(TO_DATE('''||To_char(P_DTE_VAL,'DD/MM/YYYY')||''',''DD/MM/YYYY'')) '||
AND ORDER.DHR_VALID < TRUNC(TO_DATE('''||To_char(P_DTE_VAL,'DD/MM/YYYY')||''',''DD/MM/YYYY'')) + 1 '||
AND ORDER_MVTS.MVT_TYPE = 'DELIVERY'
AND PRODUCT.CODE = ORDER_MVTS.PRODUCT_CODE
AND ORDER_MVTS.ORDER_CODE = ORDER.CODE
AND ORDER.CUSTOMER_CODE = :CUSTOMER
AND PRODUCT.CODE = :CODE ';
These two solutions work but Number 1 is bad in theory because it uses a Hint
and Number 2 may be difficult to code.
So my question is : Does someone knows another solution to force the use of index ORDER_DHR_VALID that can be simple and reliable.
Thank you very much for support
Edited by: remaï on Apr 1, 2009 4:08 PMWhat version of oracle you have? CBO work is different in 9i and 10g.
Usually cost based optimizer do not want to use index for >< condition with binding variables because optimizer can not use statistic to determine selectivity, and by default selectivity of <> operators is low.
(As I remember '>' selectivity by default is 5%, you have two conditions > and <, therefore resulting selectivity will be 0.05*0.05=0.0025 as two independent events, but selectivity of other conditions
ORDER_MVTS.MVT_TYPE = 'DELIVERY' or ORDER.CUSTOMER_CODE = 'ADIDAS' looks much better for CBO)
The best solution I see is do not use binding variables. Actually your query looks as searching query, which executes not so often, therefore you will not have perfomance win along of skipping execution plan creation.
Edited by: JustasVred on Apr 1, 2009 10:10 AM -
How to suppress SCHEMA_OWNER when using DBMS_METADATA.GET_DDL
Hi,
I was wondering, is it possible to suppress the owner when using dbms_metadata.get_ddl?
SQL> select * from v$version where rownum = 1
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
SQL> exec dbms_metadata.set_transform_param (dbms_metadata.session_transform,'SEGMENT_ATTRIBUTES',false)
SQL> select dbms_metadata.get_ddl('TABLE','EMP') from dual
DBMS_METADATA.GET_DDL('TABLE','EMP')
CREATE TABLE "SCOTT"."EMP"
( "EMPNO" NUMBER(4,0) NOT NULL ENABLE,
"ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0)
)I would like to get rid of the "SCOTT". Alternatively to change it into something else.
Is that possible, without post processing the output, that is?
Regards
PeterHi Karthick,
I was afraid that would be the answer. It can be done, but it seems rather convoluted:
SQL> create or replace function get_table_ddl(table_name varchar2
,schema varchar2 default user
,new_owner varchar2 default null)
return clob
is
v_handle number;
v_transhandle number;
v_ddl clob;
begin
v_handle := dbms_metadata.open('TABLE');
dbms_metadata.set_filter(v_handle, 'SCHEMA', schema);
dbms_metadata.set_filter(v_handle, 'NAME', table_name);
v_transhandle := dbms_metadata.add_transform(v_handle, 'MODIFY');
dbms_metadata.set_remap_param(v_transhandle,'REMAP_SCHEMA',schema,new_owner);
v_transhandle := dbms_metadata.add_transform(v_handle, 'DDL');
dbms_metadata.set_transform_param(v_transhandle,'SEGMENT_ATTRIBUTES',false);
v_ddl := dbms_metadata.fetch_clob(v_handle);
dbms_metadata.close(v_handle);
return v_ddl;
end;
Function created.
SQL> select get_table_ddl('EMP') from dual
GET_TABLE_DDL('EMP')
CREATE TABLE "EMP"
( "EMPNO" NUMBER(4,0) NOT NULL ENABLE,
"ENAME" VARCHAR2(10),
"JOB" VARCHAR2(9),
"MGR" NUMBER(4,0),
"HIREDATE" DATE,
"SAL" NUMBER(7,2),
"COMM" NUMBER(7,2),
"DEPTNO" NUMBER(2,0)
1 row selected.Regards
Peter -
K3011w - How disable the touchpad when using USB mouse?
Is there a way to disable the touchpad on the docking keybd when using a USB mouse? It is a real pain typing along and be in the middle of sentence some where else on the page.
hi whippetguy,
Thanks for Posting,
The touchpad on the dock uses a Windows driver and does not have any special Software to Disable it via shortcut,
How I found to go around on what you need is
With the tablet on the dock with no USB mouse yet
Press (Windows key+x) and choose device manager on the list
On Device Manager window open mice and pointing device and rightclick disable
This should disable the dock touchpad and Now you can plu in your USB mouse,
Before you unplu your USB mouse after use, Go to device manager again and Enable the device you disabled.
Hope this helps
Cheers!
Did someone help you today? Press the star on the left to thank them with a Kudo!
If you find a post helpful and it answers your question, please mark it as an "Accepted Solution"! This will help the rest of the Community with similar issues identify the verified solution and benefit from it.
Follow @LenovoForums on Twitter! -
How to prevent email when using find my iphone
Hi there,
Am I the only that finds the email confirmations annoying when using find my iPhone?
Is there any way to prevent these emails, or a preference somewhere to turn them off?Apple:
Considering the threads here and on other Internet sites, this is clearly a safety issue. As a parent who uses this feature on my children's phone - this feature should be optional. Notifying the bad guy when you are searching for your phone/child is not an option. Thank you.
Maybe you are looking for
-
New to the game and need some quick help
I have been thrown our exisiting phone infrastructure and what do you know we are having some issues. We have a new series of DID's and when they are dialed from our directory they go anywhere? Not routing to the proper extension. Translation patter
-
how do I add an ipad to devices in my itunes account which was previously associated with another account?
-
Looking for a simple example of the Minimax algorithm in java
Hey everyone, I'm currently working on a Gameboy emulator program as a pet project, and for one of the game's I'd like for the enemy AI to use the Minimax algorithm, but I don't have any experience with it (or recursion in general, for that matter).
-
Folks, a newbie question: Ok, so, I've not had any training, and no books, just the robohelp-html o/l help system. And I have some issues. Problem: trying to load 300 pages of old documentation into robohelp-html (webhelp format), to get it around, a
-
Passing form field values, to an external script, in a URL
We have a Dynamic, Reader Extended, Livecyce form from which we need to pass two user selected values to an external script. The values need to be passed via a URL, and cannot be static entries, but need to change based on user input. I have tried va