How BITMAP INDEX SINGLE VALUE returns rows ?
Hi guys,
here is piece from serial execution plan (display_cursor)
| Id | Operation | Name | Starts | E-Rows | A-Rows |
| 48 | PARTITION LIST ALL | | 3712 | | 4089K|
| 49 | BITMAP CONVERSION TO ROWIDS | | 40832 | | 4089K|
| 50 | BITMAP AND | | 40832 | | 23708 |
|* 51 | BITMAP INDEX SINGLE VALUE | IDX1 | 40832 | | 26014 |
|* 52 | BITMAP INDEX SINGLE VALUE | IDX2 | 40832 | | 28076 |
...What does mean such difference in A-Rows in steps 50->49, from 23708 to 4089K.
Do steps 51-52 return not regular rows but rows with bitmaps, which consist many regular rows?
853118 wrote:
here is piece from serial execution plan (display_cursor)
What does mean such difference in A-Rows in steps 50->49, from 23708 to 4089K.
Do steps 51-52 return not regular rows but rows with bitmaps, which consist many regular rows?First of all have you noticed that you have more than 40,000 starts of these operations accounted for? That explains why you see more than 1 "row" accounted for the "single value" operation. But to answer your question: Yes, a single value in a bitmap index will have one or more bitmap pieces, and each bitmap piece covers a range of ROWIDs with the bitmap (0 or 1) pattern that tells whether the value is stored in that row or not.
So a single value of a bitmap can potentially return many, if not all rows of a table. The "rows" output in the A-Rows column for bitmap indexes is probably the number of bitmap pieces (sometimes also called "fragments" I think) and therefore can look pretty small in comparison to the rows actually accessed in the table based on the information extracted from those bitmap pieces.
For more info, I recommend to have a look at Julian Dyke's presentation about bitmap index internals: http://www.juliandyke.com/Presentations/BitmapIndexInternals.ppt
Also Greg Rahn has an interesting blog post that also covers the discrepancy between "rows" of a bitmap operation and "rows" of the corresponding table access: http://structureddata.org/2008/05/29/using-bitmap-indexes-effectively/
Hope that helps,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
Co-author of the "OakTable Expert Oracle Practices" book:
http://www.apress.com/book/view/1430226684
http://www.amazon.com/Expert-Oracle-Practices-Database-Administration/dp/1430226684
Similar Messages
-
How to compare single value with multiple values
In my query I have something like this:
A.SOR_CD=B.SOR_CODE where A and B are 2 different tables. This condition is in the where clause. The column in table A has single values but some values in table B have multiple comma separated values (822, 869, 811, ..). I want to match this single
value on the left side with each of the comma separated values. Please let me know how will I be able to do it. The number of comma separated values on the right side may vary.Hi MadRad123,
According to your description, you want to compare single value with multiple values in your query. Right?
In this scenario, the table B has comma separated values, however those comma separated values are concatenated into a string. So we can use charindex() function to return the index of the table A value. And use this index as condition in
your where clause. See the sample below:
CREATE TABLE #temp1(
ID nvarchar(50),
Name nvarchar(50))
INSERT INTO #temp1 VALUES
('1','A'),
('2','A'),
('3','A'),
('4','A'),
('5','A')
CREATE TABLE #temp2(
ID nvarchar(50),
Name nvarchar(50))
INSERT INTO #temp2 VALUES
('1','a,A'),
('2','A,B'),
('3','c'),
('4','A,C'),
('5','d')
select * from #temp1 a inner join #temp2 b on a.ID=b.ID
where CHARINDEX(a.Name,b.Name)>0
The result looks like below:
Reference:
CHARINDEX (Transact-SQL)
If you have any question, please feel free to ask.
Best Regards,
Simon Hou -
How to find if cursor returned rows
If i have a procedure like
create procedure test as
cursor cur_test is
select col
from table;
begin
delete from tab1 a;
for var_cur_test in cur_test
loop
insert into temp
values(var_cur_test.col);
end loop;
commit;
end;
How do I check if the cursor has returned any rows?
I dont want to delete from tab1 if cursor 'cur_test' does not return any rows and I want to exit out of the proc.
If the cursor returns rows > 0 then I want to delete and do the insert.
Thanks for the help.The scenario is like this.
There is a schema A which has to run a process and populate its tables and at the end of the process(java program) run the procedure which is in schema B to pull data from schema A and populate the tables in schema B. If there is a case where Schema A's process fails( then Schema A's tables end up with no data), the process is still running the procedure in schema B and deleting the data in tables with no data being inserted.
So, I have to check in the procedure if the tables in Schema A have any data before the process can run the proc.
I tried the solution you provided but it returns no data
CREATE OR REPLACE PROCEDURE MMA_TEST
VAR_CONTRACT_ID VARCHAR2
AS
CURSOR CUR_TEST IS
SELECT CMS_CONTRACT_ID,CMS_PLAN_ID
FROM MMA_PLANS
WHERE CMS_CONTRACT_ID = VAR_CONTRACT_ID;
BEGIN
for var_cur_test in cur_test
loop
if (cur_test%rowcount = 1) then
delete from temp ;
end if ;
insert into temp
values(var_cur_test.cms_contract_id,var_cur_test.cms_plan_id);
end loop;
end; -
How to get SINGLE-VALUE attribute definition?
I can get the attribute definition using the following code.
// Get an attribute of that type
Attributes attrs = ctx.getAttributes("cn=Ted Geisel, ou=People",
new String[]{"cn"});
Attribute cnAttr = attrs.get("cn");
// Get its attribute definition
DirContext cnSchema = cnAttr.getAttributeDefinition();
// Get cnSchema's attributes
Attributes cnAttrs = cnSchema.getAttributes("");but all I get is SYNTAX, NAME, X-ORGIN, NUMERICOID, and DESC. In Ldap Administrator I can view the schema and under attribute types I can see SINGLE-VALUE, USAGE etc... Can anyone tell me why I can't see these values or how I can retrieve them. Thanks.Hi Sima,
then another short hint to the WD_USAGE_INITIALIZE.
Go to the component workbench, open the component BT115QH_SLSQ. Go now to the component controller class, go to it's methods. You will see that in the coding of the Method WD_USAGE_INITIALIZE, on the class CL_BT115QH__BSPWDCOMPONEN_IMPL:
WHEN 'CUGSCM' OR 'CUGSCM_DET'.
CALL METHOD iv_usage->bind_context_node
EXPORTING
iv_controller_type = cl_bsp_wd_controller=>co_type_custom
" iv_name = 'ContentManagementCuCo' "Custom Controller Name
iv_name = 'BT115QH_SLSQ/CUGSCMGenCuCo' "Custom Controller Name
iv_target_node_name = 'CMBO' "Name of Node in this Custom Controller
iv_node_2_bind = 'CMBUSOBJ'. "Name of Node in used component GS_CM
CALL METHOD iv_usage->bind_context_node
EXPORTING
iv_controller_type = cl_bsp_wd_controller=>co_type_custom
iv_name = 'BT115QH_SLSQ/CUGSCMGenCuCo'"#EC NOTEXT
iv_target_node_name = 'ATTRIBUTES' "#EC NOTEXT
iv_node_2_bind = 'ATTRIBUTES'. "#EC NOTEXT
Now I checked the context on the component controller and it contains the statusH, the node which you want to use in the component GS_CM. So make sure to prepare the GS_CM component by adding the Status context, and afterwards just add the binding in the code I pointed out above.
Best regards,
Erika -
How to hide singles values while summation
Hi
I am facing one issue in my requirement.Can some expert help me out..It will be a great help.
I need to show the sum of individual values in my report.I require sum only ,not individual values.
The report shows sum along with all its values.
when i checked option "Calculate Single value as = Hide",then those places will be blank and it shows only result.
eg Expired ID
4
But i want it to be
Expired ID 4
What would be the possible solution .....
Its urgent.Hi
Thanks a lot for a quick reply
Actually my query is like
ID Expired 41
ID expire in nxt 7 days 20
ID Overdue 14
All these are based on key figure ZCOUNTER.
Even if i hide ZCOUNTER,But the individual entries is coming blank (if i hide them) .I want to hide them completely ...
also in that case zcounter is calculating the same result for all rows.which is incorrect.
now its coming like
ID Expired 13
10
11
7
41
i want to remove these entries.... -
How to get the values returned by a function in a drop down?
Hi All,
Can anyone please help in getting the values returned by a function into a drop down? I have a java class file where in i have written a function called getWeeks() which give all the week dates and i want to display these week dates in a drop down box in a JSP page.
Please help me in this regard.
Thanks in Advance!!
Lakshman.Hi Lakshman,
the following code can help you do what you want :
<hbj:dropdownListBox id="calendar" tooltip="Calendar" selection="<%= selected %>">
<%
String[] weeks = myObjectBean.getWeeks();
for (int i = 0; i < weeks.length; i++) {
%>
<hbj:listBoxItem key="<%= i %>" value="<%= weeks<i> %>"/>
<%
%>
</hbj: dropdownListBox>
The <%= selected %> snippet allows you to pre-select one of the options (provided that the variable 'selected' is equal to one of the listBoxItem keys).
You can also add onSelect to the tag (e.g. = "setSelectedItem"). It corresponds to a method in the corresponding JSPDynPage class. This means that when you select another item in the dropdown list, the method in your Java class is performed (allowing you to save the selected value and performing actions with it)
I hope this helped you enough,
kind regards,
Frederic
Edited seven times by: Frederic Taes on Nov 5, 2008 11:24 AM -> the onSelect element was in the hbj tag and in the text with "='setSelectedItem'" next to it and when I tried to post my message, I got a 501 error all the time ! Seems like a SDN bug to me ... -
How to find duplicated values in rows obtained from multiple tables
Hi.
I need to find the duplicates stored in different tables of my database. I have some tables like the following model (I know it could be nonsense, but that's because it's simplified):
table person { id, name, surname }.
table zoo {id, owner, name, city} (zoo.owner -> person.id)
table area {id, zoo, type, name} (area.zoo -> zoo.id).
table dog {id, area, name, colour} (dog.area -> area.id)
table elephant {id, area, name, height} (elephant.area -> area.id)
As ids are autoincremental, it could happen that a person has two zoos with identical areas (meaning, these areas has the same type and name, same dogs (same name and colour) and same elephants (same name and height)). In an example with data:
person
id name surname
p1 john doe
zoo
id owner name city
z1 p1 central NY
z2 p1 central NY
area
id zoo type name
a1 z1 open main
a2 z2 open main
dog
id area name colour
d1 a1 jaro brown
d2 a1 chispa white
d3 a2 jaro brown
d4 a2 chispa white
elephant
id area name height
e1 a1 dumbo 5
e2 a1 elphy 4
e3 a2 dumbo 5
e4 a2 elphy 4
That is: John Doe has two zoos in the same city and with the same name. These two zoos, has one open main area each. Each of these areas has two dogs with the same names and colours and two elephants with the same names and heights. So this zoos would be identical. What I want is to delete z2 zoo.
I'd like to find a SQL function which returns me the id of one of these zoos, so it can respond to the question. Has the person called "John Doe" more than one area with the same type, name, dogs and elephants?
Is it possible?Hi,
Interesting problem!
Two distinct zoos are duplicates of each other if they have the same owner, the same name, the same areas, and the same animals in each of those areas.
It's pretty easy to tell if two zoos are distinct, but have the same owner and name. We could do that with a self-join:
SELECT z1.*
, z2.id AS id_2
FROM zoo z1
JOIN zoo z2 ON z1.owner = z2.owner
AND z1.name = z2.name
AND z1.id < z2.idBut how can we tell if two zoos that meet these criteria have the same aminals in the same areas? (It amuses me to call these the "critter criteria".)
One way is to make a list, for each zoo, of all the animals, with all their attributes (that is, the attributes that matter for determining if they are the same), in each area, and then see if the lists for those two zoos is identical. Like this:
WITH all_animals AS
SELECT d.id, d.area
, d.name -- || '~' || d.colour || ...
AS attributes
, 'DOG' AS animal
FROM dog d
UNION ALL
SELECT e.id, e.area
, e.name -- || '?`' || e.height || ...
AS attributes
, 'ELEPHANT' AS animal
FROM elephant e
-- UNION ALL ... cat ... monkey ...
, got_analytics AS
SELECT z.id AS zoo_id
, ar.type -- , ar.name, ...
, an.animal
, an.attributes
, COUNT (*) OVER ( PARTITION BY z.id ) AS cnt
, ROW_NUMBER () OVER ( PARTITION BY z.id
ORDER BY ar.type -- , ar.name, ...
, an.animal
, an.attributes
) AS r_num
FROM zoo z
LEFT OUTER JOIN area ar ON ar.zoo = z.id
LEFT OUTER JOIN all_animals an ON an.area = ar.id
SELECT z1.*
, z2.id AS id_2
FROM zoo z1
JOIN zoo z2 ON z1.owner = z2.owner
AND z1.name = z2.name
AND z1.id < z2.id
WHERE NOT EXISTS
SELECT type -- , name, ...
, animal, attributes
, cnt, r_num
FROM got_analytics
WHERE zoo_id = z1.id
MINUS
SELECT type -- , name, ...
, animal, attributes
, cnt, r_num
FROM got_analytics
WHERE zoo_id = z2.id
ORDER BY z1.id
, z2.id
;The first sub-query, all_animals, combines all the animals from all of the separate species tables. For each one, it makes a delimited list (the attributes column) of the columns that count in determining if 2 animals are the same. Different species may have different attributes and different numbers of attributes. The lists have to be delimited by some sub-string (not necessarily a single character) that can never occur in any of the attributes for that species. For example, dogs may never have '~' in their names (or their colours, if you expand the example to include colour). Elephants might have any character, but never have a '?' followed immediately by a grave accent '`'.
The next sub-query, got_analytics, joins the zoo and area tables to this combined list of animals. The joins are outer joins, so we can detect as duplicates two zoos that have no areas, or two areas that have no animals.
In the main query, I used MINUS to tell if the lists for two given zoos were identical. If x MINUS y produces no results, then every row in x has a matching row in y. To say that x and y are identical, we also have to know that every row in y has a matching row in x. Rather than do another MINUS, I counted the rows (got_analytics.cnt), so that if y has more rows than x, no rows will match when we do the MINUS.
Here's the output I got from your sample data:
` ID OWNER NAME ID_2
1 1 CENTRAL NY 2This shows the distinct ids, and the common attributes, of all distinct pairs of zoos that match. You can join this to the person table, if you want to see details about the owner.
If a query is correct, it will not only find all the results it is supposed to find; it will also not find all the results it is not supposed to find, for all the various reasons. I added some more sample data to test one such reason:
INSERT INTO ZOO (ID, OWNER, NAME) VALUES (91, 1, 'CENTRAL NY');
INSERT INTO AREA (ID, ZOO, TYPE) VALUES (92, 91, 'MAIN');
INSERT INTO DOG (ID, AREA, NAME) VALUES (93, 92, 'JARO');
INSERT INTO DOG (ID, AREA, NAME) VALUES (94, 92, 'CHISPA');Zoo 91 is identical to zoos 1 and 2, except that 91 has no elephants. To thoroughly test this solution, you need to add some more test data, especially zoos that will not be selected for various reasons: for example, two zoos that have all the same animals, but different numbers of areas, or that both have two areas, but the animals are distributed differently between the areas. -
How can assign the value returned from javascript to Hidden item
Hi All,
I have created a report with button in one column adding following code to SQL select statement like
SELECT USER_RQST_ID, USER_RQST_DESC, RQST_DATE, STATUS, USER_ID, CNTRY_ID, KPI_LIST, YEAR_LIST, QTR_LIST, MONTH_LIST,
PROD_LIST, FULL_PERIOD_FLG, GEN_DATE, '<input type=button value="view_list" onclick="javascript:doSubmit('||USER_RQST_ID||');">' button FROM KPI_USER_RQST;
Then i have implemet doSubmit() function in Javascript like
function doSubmit(req_id)
html_GetElement('HIDDEN_ITEM')= req_id.value;
Here HIDDEN_ITEM is the name of the item, I want to use that HIDDEN_ITEM value in PL/SQL block like...
BEGIN
INSERT INTO SAMPLE(KEY) VALUES(:HIDDEN_ITEM);
END;
But it is not working, Please help me anybody know the solution How to assign an item in javascript block function.
Thanks,
NeelHello,
doSubmit() is one of the built in javascript functions in apex and it's a bad idea to override it unless you know exactly what you are doing, and even then is a generally bad idea.
change your function to this
function mySubmit(pValue){
$x('HIDDEN_ITEM').value = pValue;
doSubmit();
then your onclick will look like this notice the lack of the javascript: and the three ''' quotes to get the proper quotations for your value.
onclick="mySubmit('''||USER_RQST_ID||''')"
And there you go
Carl -
BITMAP indexes ignored with large IN(...)
I have a fact table with 20 million records joined to a few dimension tables using 10g BITMAP INDEXes but if I add more than two or three items to my SELECT query the optimizer does not choose to use the bitmaps. For example, the first query
SELECT p.period_date, po.agent_id, count(*), SUM(ah.charge_amt)
FROM Travel_History ah, Period p, Agent po
WHERE ah.primary_agent_key = po.agent_key
AND ah.period_key = p.period_key
AND po.agent_id IN( 'DGF ', '001MG ' )
AND p.period_date =
TO_DATE( '20010701', 'YYYYMMDD' )
AND p.period_date =
TO_DATE( '20010801', 'YYYYMMDD' )
GROUP BY po.agent_id, p.period_date
definitely uses my BITMAPs as I see that in my EXECUTION PLAN (i.e. I have set autotrace on):
| 0 | SELECT STATEMENT | | 1 | 32
| 1 | HASH GROUP BY | | 1 | 32
|* 2 | FILTER | | |
| 3 | NESTED LOOPS | | 1 | 32
|* 4 | HASH JOIN | | 1 | 19
|* 5 | TABLE ACCESS FULL | PERIOD | 1 | 10
| 6 | TABLE ACCESS BY INDEX ROWID | TRAVEL_HISTORY | 4000K| 34
| 7 | BITMAP CONVERSION TO ROWIDS | | |
| 8 | BITMAP AND | | |
| 9 | BITMAP OR | | |
|* 10 | BITMAP INDEX SINGLE VALUE| XIF4TRAVEL_HISTORY | |
|* 11 | BITMAP INDEX SINGLE VALUE| XIF4TRAVEL_HISTORY | |
| 12 | BITMAP MERGE | | |
|* 13 | BITMAP INDEX RANGE SCAN | TRVLHIST_MULTI3_BMIX | |
|* 14 | BITMAP INDEX SINGLE VALUE | XIF1TRAVEL_HISTORY | |
|* 15 | TABLE ACCESS BY INDEX ROWID | AGENT | 1 | 13
|* 16 | INDEX UNIQUE SCAN | XPKAGENT | 1 |
There are only a few hundred records for those two dates, and the above query returns in
less than a second.
However, if I replace the two "period_date =" with IN(...) as:
SELECT /*+ INDEX_COMBINE( Travel_history
AcctHist_MULTI3_bmix
XIF4TRAVEL_HISTORY
XIF1TRAVEL_HISTORY )
p.period_date, po.agent_id, count(*), SUM(ah.charge_amt)
FROM Travel_History ah, Period p, Agent po
WHERE ah.primary_agent_key = po.agent_key
AND ah.period_key = p.period_key
AND po.agent_id IN( 'DGF ', '001MG ' )
AND p.period_date IN (
TO_DATE( '20010701', 'YYYYMMDD' ),
TO_DATE( '20010801', 'YYYYMMDD' ) )
GROUP BY po.agent_id, p.period_date
the execution plan goes back to
| 0 | SELECT STATEMENT | | 747 | 23904 | 45760 (7)|
| 1 | HASH GROUP BY | | 747 | 23904 | 45760 (7)|
|* 2 | FILTER | | | | |
|* 3 | HASH JOIN | | 5000K| 152M| 44897 (5)|
| 4 | MERGE JOIN CARTESIAN| | 860 | 19780 | 26 (0)|
|* 5 | TABLE ACCESS FULL | PERIOD | 4 | 40 | 6 (0)|
| 6 | BUFFER SORT | | 215 | 2795 | 20 (0)|
| 7 | TABLE ACCESS FULL | AGENT | 215 | 2795 | 5 (0)|
| 8 | TABLE ACCESS FULL | TRAVEL_HISTORY | 20M| 171M| 44527 (4)|
If I do a UNION with two SELECTs each with a unique period then the BITMAPs get used. I don't get it.
Is there any reason this would be happening???There are no bitmap indexes, there is a 64k tablespace header block containing the bitmap of occupied and free extents.
Sybrand Bakker
Senior Oracle DBA -
hi everyone,
There is table t
and there are several bitmap one-column indexes
i1 on t(c1)
i2 on t(c2)
i3 on t(c3)
Column C1 is not nullable.
Columns C2 and C3 is nullable.
There is query
select /*+ index_combine(t) */
from t
where c1 = :1
and c2 in (:2, 'X')
and c3 = :3
| Id | Operation |
| 0 | SELECT STATEMENT |
| 1 | TABLE ACCESS BY INDEX ROWID |
| 2 | BITMAP CONVERSION TO ROWIDS |
| 3 | BITMAP AND |
| 4 | BITMAP INDEX SINGLE VALUE |
| 5 | BITMAP INDEX SINGLE VALUE |
| 6 | BITMAP OR |
| 7 | BITMAP INDEX SINGLE VALUE|
| 8 | BITMAP INDEX SINGLE VALUE|
---------------------------------------Fine.
But if I create following indexes (and drop previous)
create bitmap index idx1 on t(C1, C2);
create bitmap index idx2 on t(C1, C3);
then the plan of the query above is following:
| Id | Operation |
| 0 | SELECT STATEMENT |
| 1 | TABLE ACCESS BY INDEX ROWID |
| 2 | BITMAP CONVERSION TO ROWIDS|
| 3 | BITMAP INDEX SINGLE VALUE |
--------------------------------------And the question:
why the plan does not consist BITMAP AND ?
Is it possible to scan both new indexes in the query with BITMAP AND?
Thanks793769 wrote:
Jonathan Lewis wrote:
I think this means there's a hole in the optimizer's legal strategies that you might have to fill by other methods.Do I right understand that it is impossible to combine bitmap non-one-column indexes?No, you're generalising from the particular - thus are myths created.
I have demonstrated a case where two bitmap indexes start with the same column+, and the optimizer therefore refuses to do a "bitmap and" between these two indexes when you have where clause that uses equality on the common first column and equalities on the seperate second columns. This is a very small subset of query patterns involving combinations of "non-one-column" (multi-column) indexes.
For example - why don't you try recreating your (c1, c3) index as (c3, c1) to see what the optimizer can do ?
In my example it produced the following path:
| Id | Operation | Name | Rows | Bytes | Cost |
| 0 | SELECT STATEMENT | | 10 | 1250 | 6 |
| 1 | TABLE ACCESS BY INDEX ROWID | T1 | 10 | 1250 | 6 |
| 2 | BITMAP CONVERSION TO ROWIDS| | | | |
| 3 | BITMAP AND | | | | |
|* 4 | BITMAP INDEX SINGLE VALUE| T1_B1B2 | | | |
| 5 | BITMAP MERGE | | | | |
|* 6 | BITMAP INDEX RANGE SCAN | T1_B3B1 | | | |
Predicate Information (identified by operation id):
4 - access("C1"=5 AND "C2"=50)
6 - access("C3"=50)
filter("C3"=50)So it is combining two multi column indexes - but it doesn't appear to be able to use the common column twice to make the second index access as efficient as possible. (This plan appeared for 10.2.0.3 and 11.2.0.2).
Regards
Jonathan Lewis -
Why bitmap index not working?
I have a table containing 4.2M rows and 16 distinct fs_type_code. So I created a bitmap index ntr_fs_type_code_ind on the column. Then I run the query:
update /*+ INDEX_COMBINE(NTR_FS_TYPE_CODE_IND) */ ntr_CORPALL_20050801 d
set eqt_basket_id = NULL, index_weight = NULL
where
fs_type_code in ('EQGR','EQVG','EQDL')
and eqt_basket_id = equity_symbol
and index_weight = 0;
I clearly tell optimizer to use the bitmap index. But it turns out the optimizer ignore the index and still use full table scan.
When I created regular b-tree index, the same query (without hint) use index scan.
Can anybody tell me why the bitmap index not working here?
Thanks,<quote>I clearly tell optimizer to use the bitmap index</quote>
You are clearly not doing it right (see bellow). But anyway
1. For frequently modified tables (OLTP type application) you may want to rethink the applicability of bitmap indexes
low cardinality in itself is not enough justification for using bitmap indexes.
2. Your update statement may modify a minority, a majority, or anything in between of the total number of
rows in your table here is no one universal access method which is always better
(if there were one they wouldnt have bothered with coding the rest).
In short, index access is not always the better way.
3. Dont rush into hinting (because that optimizer is such a lousy piece of software)
and if you do, make sure you do it correctly and for the right reasons.
flip@FLOP> create table t as select * from all_objects;
Table created.
flip@FLOP> insert into t select * from t;
30043 rows created.
flip@FLOP> insert into t select * from t;
60086 rows created.
flip@FLOP> insert into t select * from t;
120172 rows created.
flip@FLOP> insert into t select * from t;
240344 rows created.
flip@FLOP> create bitmap index tx on t (object_type);
Index created.
flip@FLOP> exec dbms_stats.gather_table_stats(user,'T',method_opt=>'for all indexed columns',cascade=>true)
PL/SQL procedure successfully completed.
flip@FLOP> select object_type,count(*) from t group by rollup(object_type);
OBJECT_TYPE COUNT(*)
CONSUMER GROUP 32
DIRECTORY 32
EVALUATION CONTEXT 16
FUNCTION 1648
INDEX 23152
INDEX PARTITION 2048
INDEXTYPE 128
JAVA CLASS 163024
JAVA RESOURCE 3120
LIBRARY 224
LOB 16
MATERIALIZED VIEW 32
OPERATOR 464
PACKAGE 5488
PACKAGE BODY 32
PROCEDURE 640
SEQUENCE 144
SYNONYM 202512
TABLE 18816
TABLE PARTITION 880
TRIGGER 4768
TYPE 10640
TYPE BODY 16
VIEW 42816
480688
flip@FLOP> set autotrace on explain
update few rows CBO goes with the index no hinting
flip@FLOP> update t d set object_id=object_id-1 where object_type in ('INDEX','PACKAGE','PACKAGE BODY','TABLE');
47488 rows updated.
Elapsed: 00:00:09.02
Execution Plan
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=536 Card=47488 Bytes
=1044736)
1 0 UPDATE OF 'T'
2 1 INLIST ITERATOR
3 2 BITMAP CONVERSION (TO ROWIDS)
4 3 BITMAP INDEX (SINGLE VALUE) OF 'TX'
update lots of rows CBO goes with the ft no hinting
flip@FLOP> update t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM');
365536 rows updated.
Elapsed: 00:00:25.04
Execution Plan
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=638 Card=365536 Byte
s=8041792)
1 0 UPDATE OF 'T'
2 1 TABLE ACCESS (FULL) OF 'T' (Cost=638 Card=365536 Bytes=8
041792)
update lots of rows wrong hint syntax CBO goes with the ft
flip@FLOP> update /*+ index_combine(tx) */ t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM');
365536 rows updated.
Elapsed: 00:00:21.00
Execution Plan
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=638 Card=365536 Byte
s=8041792)
1 0 UPDATE OF 'T'
2 1 TABLE ACCESS (FULL) OF 'T' (Cost=638 Card=365536 Bytes=8
041792)
update lots of rows correct hint syntax CBO goes with the index but was it better than the ft?
flip@FLOP> update /*+ index_combine(d tx) */ t d set object_id=object_id-1 where object_type in ('JAVA CLASS','SYNONYM')
365536 rows updated.
Elapsed: 00:00:25.01
Execution Plan
0 UPDATE STATEMENT Optimizer=CHOOSE (Cost=1665 Card=365536 Byt
es=8041792)
1 0 UPDATE OF 'T'
2 1 INLIST ITERATOR
3 2 BITMAP CONVERSION (TO ROWIDS)
4 3 BITMAP INDEX (SINGLE VALUE) OF 'TX'
flip@FLOP> -
I'm trying to understand why Oracle 8.1.6 sometimes uses bitmap indexes sometimes not.
Of course I have all the statistics, my bitmap indexes are valid and so on.
The problem is this:
- I have a customer table very very large
- I have many columns with bitmap indexes
- I run this statement:
select education_key, count(*)
from customer
group by education_key
and obtain a correct execution plan:
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=235 Card=5 Bytes=10)
1 0 SORT (GROUP BY NOSORT) (Cost=235 Card=5 Bytes=10)
2 1 BITMAP CONVERSION (COUNT)
3 2 BITMAP INDEX (FULL SCAN) OF 'CL_EDU'
with the use of the bitmap indexes (only five different values)
- now I want to put a condition on a column
which has a bitmap index.
The new statement is:
select education_key, count(*)
from customer
where age_key = 30
group by education_key
No join, only a scan of a sort of
fact table. In this case Oracle
doesn't use the bitmap index on
education_key:
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3458 Card=5 Bytes=20
1 0 SORT (GROUP BY) (Cost=3458 Card=5 Bytes=20)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'CUSTOMER' (Cost=3395 C
ard=18296 Bytes=73184)
3 2 BITMAP CONVERSION (TO ROWIDS)
4 3 BITMAP INDEX (SINGLE VALUE) OF 'CL_AGE'
With this execution plan Oracle has to
read some blocks from the table when I
think that using both the bitmap indexes
the query is faster.
Someone knows why Oracle has this
behaviour? I'm trying to change
many things (also altering statistics
value), but it seems that with a
condition Oracle doesn'use the bitmap
index on the group by column.
nullHi Michael, what is the address for the lasagne? ....
In init.ora.parms I had 32Mb for bitmap index merge, I suppose it's enough, hovewer I have tried to increase it and nothing changes.
I already use STAR_TRASFORMATION_ENABLED=TRUE.
I have tried with different level of statistics (estimate, compute, also with very precise histograms), always the same
behaviour. I have also tried to change, in a manual way, the statistics in order to change the Oracle behaviour but nothing ...
For this particular statement even if I use the INDEX_COMBINE hint, I mantain the same execution plan.
I use CHOOSE, FIRST_ROWS, ALL_ROWS: always the same behaviour.
I think that Oracle is not able to use a bitmap index on a column involved in a group by when there is another condition in the select.
Hovewer with bitmap indexes, I have many other problems (to read 1% of the table Oracle decides to make a full table scan even if there are the correct bitmap indexes ...).
Many of them are solved using BITMAP_INDEX, but it's difficult to use it in a query tool like Discover or Business Objects because I have to fix the use of INDEX_COMBINE also in situation in which this use is not correct from a performance point of view.
The life with the query optimizer is very hard!
Thank you for your guesses -
How to find dynamic value(screen value) in table control for current row .
hi to all,
i used table control in my screen. for column no 2 field i was used serrch help. and for column number 3 i used a dynamic help.
in change mode you can change any row for table control.
when i was using search help for a row which was already entered in column no 3 i cannot get any value.
how i can get value of row no 3 and column no 2 value.
thanksTry using like index for the serarch the TC-current_line
-
Hi All,
Could some one please let me know how Bitmap indexes are useful compared to B-Tree indexes on low-cardinality columns ?.
Thanks,
-Kumar.>>
As Re: why oracle db 9i optimizer can't choose to use the bitmap index? there are a number of issues with bitmap indexes. Your best bet is to read these three articles by Jonathan Lewis.
It does pay us to understand how the optimizer works with bitmap indexes. I posted some Re: Cost-based optimizer behavior to show how indexes on even very low valued columns can be useful in certain circumstances.
Cheers, APC
Blog : http://radiofreetooting.blogspot.com/ -
How to display 7 values of single field in row wise.
hi,
how to display 7 values of single field in row wise.
thankx in advance.hi ,
do it like this :
1 Place ur UI element in tranparent container with Layout as Row Data and Layout Data as Row Head Data
2 Ur first UI , which contains the first value as Row Head Data ,
3 Others as Row Data
u can do it with Matrix Data as well
if u want to give space , u can use HORIZONTAL GUTTER and set its width to medium / large / Xlarge
also there is a UI element "INVISIBLE ELEMENT" ,
1 u can use this UI element to provide space between ur other UI elements in the view
2 u can insert a text element as well , and in the Text property of the element press ALT + 0160.
u can give the space bw UIs as desired.
regards,
amit
Maybe you are looking for
-
Preventing the creation of direct PO
Hi there experts, I would like to know if there is some way to prevent the creation of direct PO. I want that the PO is always created with reference to a PR or a contract. Tanks in advance
-
Uploading songs from laptop to ipad mini
how to upload songs from laptop to ipad mini
-
Excessive lag in VI on Mac, but not Windows
I have created a VI that accepts user input to collect, save, and open voltage waveforms from a DAQmx board. It is a while loop and a state machine with a lot of information in it so I understand that efficiency might be an issue. This lag only exist
-
How to migrate content from BW 3.1 to NetWeaver 7.0
Hello all out there, For a couple of years I have been successfully using SDN, finding always the right answer to my questions, however in my late assignment things have not been running that smoothly. This is my first posting to SDN and I hope any o
-
Need to add more field in the selection screen in tcode crm_dno_monitor
Hi, In the transaction code crm_dno_monitor, i need to add extra fields in selection screen. Do we have any way to add fields in the standard tcode crm_dno_monitor. Thanks Prasad