Search

OakieTags

Who's online

There are currently 0 users and 22 guests online.

Recent comments

Affiliations

January 2011

ANSI Outer

Here’s an example of ANSI SQL that does something in a fashion that arguably looks a little tidier than the strategy you have to adopt in Oracle. As so often when I compare Oracle syntax and ANSI syntax it’s an exanple that relates to an outer join. We start with two tables – as usual I have locally managed tablespaces, 8KB blocks, 1MB uniform extents and freelist management. I’ve also disabled system statistics (CPU costing):


create table t1
as
select
	rownum - 1			id,
	mod(rownum - 1,20)		n1,
	lpad(rownum - 1,10,'0')		v1,
	rpad('x',100)			padding
from
	all_objects
where
	rownum <= 4000
;

create table t2
as
select
	rownum - 1			id,
	mod(rownum - 1,20)		n1,
	lpad(rownum - 1,10,'0')		v1,
	rpad('x',100)			padding
from
	all_objects
where
	rownum <= 4000
;

create index t1_i1 on t1(id);
create index t2_i1 on t2(id);

begin
	dbms_stats.gather_table_stats(
		ownname		 => user,
		tabname		 =>'T1',
		estimate_percent => 100,
		method_opt 	 => 'for all columns size 1'
	);

	dbms_stats.gather_table_stats(
		ownname		 => user,
		tabname		 =>'T2',
		estimate_percent => 100,
		method_opt 	 => 'for all columns size 1'
	);

end;
/

If you're familiar with ANSI SQL you won't need more than a couple of moments to interpret the following query - but I have to admit that I had to think about it carefully before I figured out what it was trying to achieve:


select
	/*+ gather_plan_statistics */
	t1.id,
	t1.n1,
	t1.v1,
	t2.n1
from
	t1
left join
	t2
on
	t2.id = t1.n1
and	t1.n1 in (7, 11, 13)
where
	t1.id = 15
;

        ID         N1 V1                 N1
---------- ---------- ---------- ----------
        15         15 0000000015

--------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------
|   1 |  NESTED LOOPS OUTER            |       |      1 |      1 |      1 |00:00:00.01 |       4 |
|   2 |   TABLE ACCESS BY INDEX ROWID  | T1    |      1 |      1 |      1 |00:00:00.01 |       4 |
|*  3 |    INDEX RANGE SCAN            | T1_I1 |      1 |      1 |      1 |00:00:00.01 |       3 |
|   4 |   VIEW                         |       |      1 |      1 |      0 |00:00:00.01 |       0 |
|*  5 |    FILTER                      |       |      1 |        |      0 |00:00:00.01 |       0 |
|   6 |     TABLE ACCESS BY INDEX ROWID| T2    |      0 |      1 |      0 |00:00:00.01 |       0 |
|*  7 |      INDEX RANGE SCAN          | T2_I1 |      0 |      1 |      0 |00:00:00.01 |       0 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("T1"."ID"=15)
   5 - filter(("T1"."N1"=7 OR "T1"."N1"=11 OR "T1"."N1"=13))
   7 - access("T2"."ID"="T1"."N1")
       filter(("T2"."ID"=7 OR "T2"."ID"=11 OR "T2"."ID"=13))

Look carefully at the query. The ON clause includes a reference to the t1 table that is NOT a join condition. This condition means that Oracle will try to find a matching row in t2 only if the n1 value in t1 is in 7,11, or 13.

Since the join is left outer, any t1 row where id = 15 will be returned, but the n1 column from t2 will be reported only if the t1.n1 value is in 7,11, or 13 and there is a t2 row with a matching id value.

How would you express the same requirment in standard Oracle syntax ? Here's one possibility:

select
	/*+ gather_plan_statistics */
	t1.id,
	t1.n1,
	t1.v1,
	t2.n1
from
	t1, t2
where
	t1.id = 15
and	t2.id(+) = case
		when t1.n1 not in (7, 11, 13)
		 	then null
			else t1.n1
	end
;

        ID         N1 V1                 N1
---------- ---------- ---------- ----------
        15         15 0000000015

------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------------
|   1 |  NESTED LOOPS OUTER          |       |      1 |      1 |      1 |00:00:00.01 |       4 |
|   2 |   TABLE ACCESS BY INDEX ROWID| T1    |      1 |      1 |      1 |00:00:00.01 |       4 |
|*  3 |    INDEX RANGE SCAN          | T1_I1 |      1 |      1 |      1 |00:00:00.01 |       3 |
|   4 |   TABLE ACCESS BY INDEX ROWID| T2    |      1 |      1 |      0 |00:00:00.01 |       0 |
|*  5 |    INDEX RANGE SCAN          | T2_I1 |      1 |      1 |      0 |00:00:00.01 |       0 |
------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("T1"."ID"=15)
   5 - access("T2"."ID"=CASE  WHEN (("T1"."N1"<>7) AND ("T1"."N1"<>11) AND
              ("T1"."N1"<>13)) THEN NULL ELSE "T1"."N1" END )

You will have noticed that I used the /*+ gather_plan_statistics */ hint in both queries, and the plans I've shown are the ones that I pulled from memory with their last execution statistics included.

The plans are clearly just a little different from each other - but are they equally efficient ?

Both plans start the same way - for each relevant row in t1 they call line 4 - and in both cases there is only one relevant row in t1, hence one call to line 4.

In the first plan we call the subroutine to create a rowsource (the VIEW operator), and this calls the FILTER operation. The filter operation is an example of a "conditional" filter - i.e. if the test in line 5 is true then line 6 is called - and in this case the test is false so line 6 is never called (Starts = 0) and Oracle doesn't try to access table t2. So we fetch one row from t1, then call two subroutines that between them do a "case" test but access no data blocks.

In the second plan line 4 calls the table access operation, which calls the index range scan operation in line 5 - but line 5 starts with a call to the case statement that returns NULL - so even though we call the index range scan operation, we don't access any data blocks, which means we don't pass any rowids to the table access in line 4, which means that that operation doesn't access any data blocks. The net workload is that lines 4 and 5 in the second plan also represent nothing more than two subroutine calls and a "case" test.

The two plans are virtually identical in resource usage - so your choice of which to use probably comes down to aesthetic appeal and comfort factor. Thanks to my previous habits I think the Oracle variant is "obviously" much easier to understand - but the client probably felt the opposite because they spent most of their time writing ANSI.

Is there another way to write the query - yes, there is, but for some reason it's not supported. If you look at the 10053 trace file for the ANSI example you'll find that Oracle has rewritten it with a LATERAL subquery before optimising it. So, presumably, we can appply the same transformation manually:


select
	/*+ gather_plan_statistics */
	t1.id,
	t1.n1,
	t1.v1,
	t2.n1
from
	t1,
	lateral (
		(
		select
			t2.n1
		from
			t2
		where
			t1.n1 in (7, 11, 13)
		and	t2.id = t1.n1
		)
	)(+) t2
where
	t1.id = 15
;

        lateral (
                *
ERROR at line 9:
ORA-00933: SQL command not properly ended

On second thoughts perhaps we can't - but it was a nice idea.

Oracle uses the table() operator with collections (or pipelined functions) as the equivalent of the ANSI LATERAL() operator, but doesn't let you use it with queries (you get Oracle error "ORA-22905: cannot access rows from a non-nested table item" if you try).

The concept is simple - the table() or lateral() operator allows you to introduce a subquery in the FROM clause that references columns from a table that appears earlier in the same FROM clause.

I don't know why Oracle doesn't support the lateral() operator in end-user code - but actually, for experimental purposes only of course, if you want to play with it you can always set event 22829:


alter session set events '22829 trace name context forever';

-- execute lateral query, and get this plan

--------------------------------------------------------------------------------------------------
| Id  | Operation                      | Name  | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
--------------------------------------------------------------------------------------------------
|   1 |  NESTED LOOPS OUTER            |       |      1 |      1 |      1 |00:00:00.01 |       4 |
|   2 |   TABLE ACCESS BY INDEX ROWID  | T1    |      1 |      1 |      1 |00:00:00.01 |       4 |
|*  3 |    INDEX RANGE SCAN            | T1_I1 |      1 |      1 |      1 |00:00:00.01 |       3 |
|   4 |   VIEW                         |       |      1 |      1 |      0 |00:00:00.01 |       0 |
|*  5 |    FILTER                      |       |      1 |        |      0 |00:00:00.01 |       0 |
|   6 |     TABLE ACCESS BY INDEX ROWID| T2    |      0 |      1 |      0 |00:00:00.01 |       0 |
|*  7 |      INDEX RANGE SCAN          | T2_I1 |      0 |      1 |      0 |00:00:00.01 |       0 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   3 - access("T1"."ID"=15)
   5 - filter(("T1"."N1"=7 OR "T1"."N1"=11 OR "T1"."N1"=13))
   7 - access("T2"."ID"="T1"."N1")
       filter(("T2"."ID"=7 OR "T2"."ID"=11 OR "T2"."ID"=13))

The plan is identical to the plan for the ANSI after transformation. I'll leave it to you to decide whether the code is easier to understand than the ANSI or ordinary Oracle versions - but I'd like to see it made legal, even if I didn't find many cases where I needed it.

The Mechanic…

The Mechanic was an OK film. It didn’t have the style of The Transporter franchise, or the grittiness of the Bourne franchise, but it was obviously meant to appeal to that fan base.

I like Jason Statham in action films. He moves well and works angles really nicely. There wasn’t really any of that in this film. Kinda wasting his best feature in my opinion.

Ben Foster has carved himself a really good niche as an intense nutter. He does it really well and was one of the best things in the film. I was just watching the screen waiting for him to go pop. :)

All in all, not the worst visit to the cinema, but not really as good as I was hoping.

Cheers

Tim…

Do virtual keyboards promote weak passwords?

I’m quite big on password complexity. I like to use mixed case, numbers and special characters in my passwords.

Since having the iPad (and now the Android phone) I find it a real bind typing in strong passwords. The mixed case isn’t so bad, but I do have more login mistakes with the virtual keyboard. What really bugs me is having to switch keyboards two or three times to get all the special characters and numbers in. Every time I have to type a password on a mobile device I feel a certain tension…

My recent experience has left me thinking how nice it would be to have a weak password, preferably lower case letters only. So my next thought was, do virtual keyboards promote weak passwords?

Of course, I don’t expect anyone to comment and admit they have switched back to weak passwords, but it would be nice to know if anyone else feels my pain… :)

Cheers

Tim…

REWORK…

A recent thread on the OakTable mailing list about company policies got me a little fired up. In reply to my extended rant Cary Millsap suggested I read REWORK.

Let me start by saying I’m not a fan of self-help books and I don’t consider myself a business person, so a book that looks like self-help for businesses just didn’t seem like a good fit. I have little-to-no ambition in terms of the business world or money. Having said that, I play in a world where ambition and money are central, so I figured I’d give it a go.

REWORK distills and debunks many of the myths associated with modern business. For anyone who has worked in the IT industry for a few years, the central messages are not new. You will have thought about a lot of these issues many times, probably while you were in a 3 hour meeting to discuss why you missed a deadline…

I guess I’m in agreement with about 95% of the suggestions in the book and even those I disagree with, I can see the point. If you are running a business, want to run a business, or just trying to understand why the company you work for is so messed up, you should read this book. It’s a bit like group therapy. It’s good to know you are not alone… :)

Big thanks to Cary for the suggestion. I have a couple of mates (who still have some ambition left) who will benefit from it more than me. I’ll be sure to pass it on.

Cheers

Tim…

storage(:Z>=:Z AND :Z

Ever wonder why that weird line shows up in the Predicate Section of an execution plan on Exadata? Me too! The STORAGE bit tells us it’s a filter applied at the storage cell layer, but the rest is nonsensical. Well I recently ran across a very brief mention of it in a Metalink note. (I know it’s not called Metalink any more, but I’m kind of set in my ways). The note said it was related to distribution of rows to PX slaves. Ah ha! Let’s test it out. Here’s a plan with the predicate just so you can see what it looks like.

KSO@arcp> @dplan
Enter value for sql_id: a9axwj6ym3b29
Enter value for child_no: 
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  a9axwj6ym3b29, child number 0
-------------------------------------
select /*+  parallel_index(t, "ISD_SI_I03",8)  dbms_stats
cursor_sharing_exact use_weak_name_resl dynamic_sampling(0)
no_monitoring no_substrb_pad  no_expand index_ffs(t,"ISD_SI_I03") */
count(*) as nrw,count(distinct sys_op_lbid(725425,'L',t.rowid)) as
nlb,count(distinct hextoraw(sys_op_descend("SUPPORT_LEVEL")||sys_op_desc
end("SUPPORT_LEVEL_KEY")||sys_op_descend("NAME")||sys_op_descend("VALUE"
))) as ndk,sys_op_countchg(substrb(t.rowid,1,15),1) as clf from
"ISD"."SUPPORT_INFO" sample block (   .0503530742,1)  t where
"SUPPORT_LEVEL" is not null or "SUPPORT_LEVEL_KEY" is not null or
"NAME" is not null or "VALUE" is not null
 
Plan hash value: 1766555783
 
---------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                                   | Name       | Rows  | Bytes | Cost (%CPU)| Time     |    TQ  |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                            |            |       |       |   672 (100)|          |        |      |            |
|   1 |  SORT GROUP BY                              |            |     1 |    56 |            |          |        |      |            |
|   2 |   PX COORDINATOR                            |            |       |       |            |          |        |      |            |
|   3 |    PX SEND QC (RANDOM)                      | :TQ10001   |     1 |    56 |            |          |  Q1,01 | P->S | QC (RAND)  |
|   4 |     SORT GROUP BY                           |            |     1 |    56 |            |          |  Q1,01 | PCWP |            |
|   5 |      PX RECEIVE                             |            |     1 |    56 |            |          |  Q1,01 | PCWP |            |
|   6 |       PX SEND HASH                          | :TQ10000   |     1 |    56 |            |          |  Q1,00 | P->P | HASH       |
|   7 |        SORT GROUP BY                        |            |     1 |    56 |            |          |  Q1,00 | PCWP |            |
|   8 |         PX BLOCK ITERATOR                   |            |   397K|    21M|   672   (1)| 00:00:01 |  Q1,00 | PCWC |            |
|*  9 |          INDEX STORAGE SAMPLE FAST FULL SCAN| ISD_SI_I03 |   397K|    21M|   672   (1)| 00:00:01 |  Q1,00 | PCWP |            |
---------------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   9 - storage(:Z>=:Z AND :Z<=:Z AND ("SUPPORT_LEVEL" IS NOT NULL OR "SUPPORT_LEVEL_KEY" IS NOT NULL OR "NAME" IS NOT NULL OR
              "VALUE" IS NOT NULL))
       filter(("SUPPORT_LEVEL" IS NOT NULL OR "SUPPORT_LEVEL_KEY" IS NOT NULL OR "NAME" IS NOT NULL OR "VALUE" IS NOT NULL))
 
 
37 rows selected.

Notice that the plan is for a PX statement. So how can we convince ourselves that it is a PX related predicate. We can try two tests.

  1. Let’s see if we can find any SQL statements that have the predicate that aren’t PX statements.
  2. Let’s see if we can find any PX statements that don’t have the predicate.

So here we go.

KSO@arcp>  -- How many :Z>=:Z's are there?
KSO@arcp> select count(*) from v$sql_plan
  2  where ACCESS_PREDICATES like '%:Z>=:Z%'
  3  /
 
  COUNT(*)
----------
        73
 
1 row selected.
 
KSO@arcp>  -- How many :Z>=:Z's are there that are not PX?
KSO@arcp> select count(*) from v$sql_plan
  2  where ACCESS_PREDICATES like '%:Z>=:Z%'
  3  and sql_id not in (select sql_id from v$sql_plan where operation like 'PX%')
  4  /
 
  COUNT(*)
----------
         0
 
1 row selected.
 
KSO@arcp>  -- How many PX's don't have :Z>=:Z?
KSO@arcp> select count(distinct sql_id) from v$sql_plan
  2  where operation like 'PX%'
  3  and sql_id not in (select sql_id from v$sql_plan
  4  where ACCESS_PREDICATES like '%:Z>=:Z%')
  5  /
 
  COUNT(*)
----------
       154
 
1 row selected.
 
KSO@arcp>  -- Whoa, that's a little unexpected!

So there are none of the :Z>=:Z predicates on non-PX queries but there are a bunch of PX queries that don’t have the predicate. Let’s look at a couple of those and see why those might not have the predicate.

 
KSO@arcp> -- Get SQL_ID's for PX's that don't have :Z>=:Z
KSO@arcp> select distinct sql_id from v$sql_plan
  2  where operation like 'PX%'
  3  and sql_id not in (select sql_id from v$sql_plan
  4  where ACCESS_PREDICATES like '%:Z>=:Z%')
  5  /
 
SQL_ID
-------------
7xa3zbpgkbta7
ftkmqqq3ga0nf
6wgmq24t9xy6f
7tsf3h3qjth77
fg1aphaqvcmb3
...
bt9n0qsg8k4sb
fffrvvnrnmztg
97x3zj2fb0y5z
5dudhrch3sv8r
bbw31mhra7ryu
 
154 rows selected.
 
KSO@arcp> @dplan
KSO@arcp> set lines 150
KSO@arcp> select * from table(dbms_xplan.display_cursor('&sql_id','&child_no','typical'))
  2  /
Enter value for sql_id: bbw31mhra7ryu
Enter value for child_no: 
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  bbw31mhra7ryu, child number 0
-------------------------------------
select MUTEX_TYPE, LOCATION, SLEEPS, WAIT_TIME from GV$MUTEX_SLEEP
where INST_ID = USERENV('INSTANCE')
 
Plan hash value: 365768877
 
----------------------------------------------------------------------------
| Id  | Operation            | Name           |    TQ  |IN-OUT| PQ Distrib |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                |        |      |            |
|*  1 |  PX COORDINATOR      |                |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000       |  Q1,00 | P->S | QC (RAND)  |
|*  3 |    VIEW              | GV$MUTEX_SLEEP |  Q1,00 | PCWP |            |
|   4 |     FIXED TABLE FULL | X$MUTEX_SLEEP  |  Q1,00 | PCWP |            |
----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("INST_ID"=USERENV('INSTANCE'))
   3 - filter("INST_ID"=USERENV('INSTANCE'))
 
Note
-----
   - rule based optimizer used (consider using cbo)
 
 
27 rows selected.
 
KSO@arcp> 
KSO@arcp> /
Enter value for sql_id: 5dudhrch3sv8r
Enter value for child_no: 
 
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  5dudhrch3sv8r, child number 0
-------------------------------------
select  NAMESPACE , GETS , GETHITS , GETHITRATIO , PINS , PINHITS ,
PINHITRATIO , RELOADS , INVALIDATIONS , DLM_LOCK_REQUESTS ,
DLM_PIN_REQUESTS , DLM_PIN_RELEASES , DLM_INVALIDATION_REQUESTS ,
DLM_INVALIDATIONS from GV$LIBRARYCACHE where inst_id =
USERENV('Instance')
 
Plan hash value: 3363616119
 
-----------------------------------------------------------------------------
| Id  | Operation            | Name            |    TQ  |IN-OUT| PQ Distrib |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                 |        |      |            |
|*  1 |  PX COORDINATOR      |                 |        |      |            |
|   2 |   PX SEND QC (RANDOM)| :TQ10000        |  Q1,00 | P->S | QC (RAND)  |
|*  3 |    VIEW              | GV$LIBRARYCACHE |  Q1,00 | PCWP |            |
|*  4 |     FIXED TABLE FULL | X$KGLST         |  Q1,00 | PCWP |            |
-----------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("INST_ID"=USERENV('INSTANCE'))
   3 - filter("INST_ID"=USERENV('INSTANCE'))
   4 - filter((LENGTH("KGLSTDSC")<=15 AND "KGLSTGET"<>0 AND
              "KGLSTTYP"='NAMESPACE'))
 
Note
-----
   - rule based optimizer used (consider using cbo)
 
 
32 rows selected.

So both of those queries are against Fixed Tables (memory structures). Makes sense that a filter at the storage layer would not be necessary. As it turns out, all 154 of the PX queries that don’t have the :Z>=:Z predicate are queries against Fixed Tables. Here’s a quick check in case you want to try it on your own Exadata.

 
KSO@arcp> select count(*) from v$sql_plan
  2  where operation like 'PX%'
  3  and sql_id not in (select sql_id from v$sql_plan
  4  where ACCESS_PREDICATES like '%:Z>=:Z%')
  5  and sql_id not in (select sql_id from v$sql_plan
  6  where operation not like 'FIXED%')
  7  /
 
  COUNT(*)
----------
         0
 
1 row selected.

So while not a definitive proof, it does appear that the :Z>=:Z predicate is related to PX row distribution. Now if I can just figure out why the storage filters are always repeated in the XPLAN output as a standard filter for offloaded queries like in this example:

Enter value for sql_id: 0qa98gcnnza7h
Enter value for child_no: 
 
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID  0qa98gcnnza7h, child number 0
-------------------------------------
select avg(pk_col) from kso.skew where col1 > 0
 
Plan hash value: 568322376
 
-----------------------------------------------------------------------------------
| Id  | Operation                  | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------------
|   0 | SELECT STATEMENT           |      |       |       | 44486 (100)|          |
|   1 |  SORT AGGREGATE            |      |     1 |    11 |            |          |
|*  2 |   TABLE ACCESS STORAGE FULL| SKEW |    32M|   335M| 44486   (1)| 00:08:54 |
-----------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - storage("COL1">0)
       filter("COL1">0)
 
 
20 rows selected.

Let me know if you have the answer to that one!

Migrating your VMs from VMware to VirtualBox (on a Netbook)


I recently bought a Toshiba nb305-n600 10.1″ netbook with Windows 7 Starter (32bit) on Atom n550, 250GB 5400 rpm disk, & 2GB of physical memory. 

Well this netbook has thrice the battery life (or more) and half the weight of my old laptop ;) so I must say it’s really good for everyday use!

But as a DBA, I would be happier if I can run my VMware VMs on this lightweight lappie!

Do you really care about your social network friends?

I read a post on Slashdot called Who Unfriended You, and Why. You’ve got to be one insecure puppy if you are concerned about this junk.

I went on to LinkedIn yesterday and approved loads of connection requests. Of those people, the only person I think I know is the guy who massages my back before I see the Osteopath. The rest are a complete mystery to me. I’m kinda similar on Mix, the Oracle Community and the Oracle Wiki. I link to anyone who requests. I think it was yesterday that I read something (can’t find link) about Facebook having the edge over Google in the future of searches because they know so much more about you. Really? If linking is a factor I think more is definitely less!

Facebook is the only social network where I actively control my linking. With a couple of exceptions, all my friends on Facebook are people I know in real life and would consider proper friends (current or past). I even exclude “proper friends” within the Oracle community because I’m linked to them in so many other ways it seems pointless to clutter my Facebook with them. If you send a friend request to me on Facebook you are likely to get ignored, so don’t be offended, it’s just the way I use that site.

So back to the point, my use of Facebook means that the links there have value right? Surely if these people are my “proper friends” I will share a lot in common with them and you will be able to target me based on them and vice versa. Recently my Facebook has contained the following topics:

  • Babies: Food and sleeping patterns of babies have been by far the biggest subject for a few months. I have no kids. FAIL.
  • Gay poetry with a radical political edge: One of my friends from University is now a gay poet who is apparently pretty good. Never read his work. Not my scene. My interest in politics goes about as far as pointing out how retarded most political decisions are. FAIL.
  • Hill running: Look at me. Do I look like I could walk up a hill, let alone run up one? FAIL.
  • Local football teams: Football is not really my thing. If my nephews didn’t play it I could happily forget it exists. FAIL.
  • DJ and clubbing stuff: A couple of my friends are DJs so there are often posts about and invites to local club nights. I don’t do clubs. FAIL.

What is not included in that list is anything computer or database related. Oh dear. The thing you could really target me on is the only thing missing from my Facebook because the majority of my proper friends are not IT people.

Given the complete random way some people build their networks and the random guff they talk about, I don’t really think Google should be quaking in their boots quite yet. A bigger problem for them is the number of people that never leave Facebook and therefore never see Google ads on the rest of the web, not the [lack of] quality of information Facebook holds about us.

Cheers

Tim…

Caveats: I realize there is more to online marketing than this, but it was just an illustration of how random social networks can be.

Histograms and Bind Variables, But Why?

January 29, 2011 In a recent OTN thread a person asked a couple of good questions about why histograms and the use of bind variables sometimes cause problems.  The questions did not ask whether or not one should use histograms on the table columns where those columns often appear in WHERE clauses, with the columns compared to  bind [...]

Fix Control

There’s a very useful posting from Coskan Gundogar about tracking down a problem to do with an 11g upgrade.

The method basically revolves around a quick check for “known issues” that might be relevant by looking at the dynamic performance views v$system_fix_control.

When I read Coskan’s notes I had forgotten that I had written a short item about this myself about a year ago where I listed the  relatively small number of  items available in 10.2.0.3. The list is up to 551 in my copy of 11.2.0.2.

 

Where’s my money gone? (again)…

Followers of the blog will know before Christmas Oracle Norway randomly took a few thousand pounds off one my credit cards. The various accounting departments have been chasing their tails ever since and have only really proved they don’t know their arse from their elbow.

It’s now a month later and what do I see on my account but another payment to Oracle Norway. Sigh…

I’m on the phone now getting the transaction dealt with by the fraud department of the credit card company and getting the card cancelled. I guess I should have cancelled the card last time but I foolishly thought Oracle would be able to find out who and why my credit card was charged. It seems that is beyond their accounting system. Maybe Fusion Apps will allow you to track that information…

Cheers

Tim…