tag:blogger.com,1999:blog-119956382007-11-27T13:05:49.635-07:00Oracle Sponge -- Now Moved To WordpressPlease use http://oraclesponge.wordpress.comDavid Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comBlogger191125tag:blogger.com,1999:blog-11995638.post-1150148175997813812006-06-12T15:31:00.000-06:002006-06-12T15:36:16.140-06:00Moving to WordPressBlogger irritates me. Let's see if Wordpress makes me happy.<br /><br />http://oraclesponge.wordpress.com/<br /><br />I've used the supplied import functionality to move over posts and comments, and it seems to have gone pretty well. Internal links need to be resolved to the new UR, and some text formatting has gone astray, but I can work my way through that.<br /><br />The category functionality is great, and the interface is much more snappy, so I'll probably stick with it.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1149278502214746742006-06-02T13:45:00.000-06:002006-06-02T14:01:42.270-06:00Modelling of CondominiumsA condominium in this case being a geographical area of which two of more sovereignties agree to share dominium, but that title ought to do wonders for my statistics.<br /><br />Anyway, I was thinking about the mapping between cities and zip codes today, which is a many-to-many relationship, and the thought popped into my head, "I wonder if there are any cities which belong to multiple countries?" In other words, are there any cities which are part of a <a href="http://en.wikipedia.org/wiki/Condominium_%28international_law%29">condominium</a>?<br /><br />So I went looking for one, not expecting to find any, and I was right -- there appear to be none. Probably a good job too.<br /><br />In fact the only decent example of a condominium currently in effect seems to be that of <a href="http://maps.google.com/maps?f=q&hl=en&q=hendaye,+spain&ll=43.342845,-1.765366&spn=0.001802,0.005364&t=k&om=1">Pheasant Island</a>, which is a condominium of France and Spain. It apparantly is shared on a six-monthly basis between the two nations, which leads to an interesting modelling problem -- a cyclic time-dependent relationship between geography and sovereignty. In other words, it's a time-share! (Stats again).<br /><br />Anyway, I'll leave that as "an exercise for the reader".<br /><br />It also raises anther question: back when one needed a passport to cross between the two countries, was a crime commited if a passport-less person was present on the island at the time that sovereignty changed? Perhaps none -- perhaps the condominium agreement allowed people of either nationality to be present on the island at any time, regardless of which state currently was in charge of it. But if the agreement did not allow this then could you charge a person with crossing a border if they were stationary at the time the offence occured?<br /><br />These thoughts usually turn-up on Fridays, oddly enough. Must be something to do with blood sugar.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1148332599000247382006-05-22T15:08:00.000-06:002006-05-22T15:16:39.073-06:00The Prime Number FewI was chasing links through Wikipedia the other day, which always leads somewhere interesting.<br /><br />In this case I fell into the deep waters of linguistics and learned about <a href="http://en.wikipedia.org/wiki/Garden_path_sentence">garden path sentences</a>. They caught my eye in particular because the article includes one of my favourite jokes, albeit with a slightly different construction to my usual one.<br /><br /><div style="text-align: center;"><span style="font-style: italic; font-weight: bold;">"If time flies like an arrow, do fruit flies like a banana?"</span><br /></div><br />Now that I've read a deconstruction of the joke, it seems a little less funny though.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1147971366570752222006-05-18T07:00:00.000-06:002006-05-18T12:50:26.886-06:00The Three Pillars of Oracle Data Warehousing<span style="font-weight: bold; font-style: italic;">Introduction</span><br /><br />This is a basic topic for Oracle data warehousing beginners, based on some ideas that I'm hoping will stop buzzing round in my head if I commit them to virtual paper.<br /><br />There are three Oracle features that provide a foundation for successful data warehousing:<br /><ul> <li><span style="font-weight: bold;font-size:130%;" >P</span>artitioning</li> <li><span style="font-weight: bold;font-size:130%;" >P</span>arallelism</li> <li><span style="font-weight: bold;font-size:130%;" >P</span>summary Tables (the "p" is silent)</li> </ul> Here are the benefits that they bring to the system.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">Partitioning</span><br /><br />In a data warehouse we are interested in accessing large numbers of rows that are identified through some common attribute. Very often the same small numbers of attributes are used over and over again to filter the data. The most common is some form of date filter ("give me sales for<span style="font-style: italic;"> this </span><span style="font-style: italic;">January</span>"), and there are often others that are used very commonly ("give me inventory levels for <span style="font-style: italic;">repairable</span> items", "give me backorders for <span style="font-style: italic;">California</span>").<br /><br />In an OLTP system we would use an index or a full tablescan to get this subset of data, but that can be inefficient if we are selecting a large number of rows representing a subset of the total table data because of the high number of logical i/o's required and the single block reads that are used to access the table.<br /><br />In a data warehouse we can partition according to attributes commonly used as filters by the users, or according to logical child attributes of them (eg. users commonly filter by month but we partition by day). This achieves two important aims.<br /><ol> <li>Rows of data that are commonly used together are physically co-located.</li> <li>The optimizer can treat each partition as a table and can perform fast scans of multiple partitions to access the data ("partition pruning").</li> </ol>We can also use multicolumn or composite partitioning to partition by multiple attributes, so that we can partition both by date and by location and get partition pruning on either or both.<br /><br />There are also benefits to manipulating bulk data -- we can use partition-based DDL operations to load and unload data from a table (a partition exchange) or to delete old data (partition drop or truncate).<br /><br /><br /><span style="font-weight: bold; font-style: italic;">Parallelism</span><br /><br />In a parallel query operation the physical locations in which the required rows are held are subdivided into a number of ranges, each of which is then scanned by a different process<br />(a parallel query slave). The processes that read the data then pass it on to either a single query coordinator process or to another set of slaves which themselves pass the results to the query coordinator.<br /><br />Insert, update and delete operations can also be parallelized to provide faster bulk data changes.<br /><br />One of the key differences between serial and parallel queries are that the parallel queries read data directly from disk instead of checking for the required blocks in the SGAs block buffer area, and pass the result set directly to the user's PGA, thus completely bypassing the SGA. Read consistency is maintained through the query coordinator requesting a checkpoint to have commited dirty buffers of the scanned object written to disk before the PQ slaves start reading.<br /><br />The coordination required in creating and controlling query slaves leads to an overall increase in resource usage which can easily overload a system, but when correctly implemented spare system resources can be used to improve the response time of queries that access or manipulate a large amount of data.<br /><br />You probably need a lower degree of parallelism than you expect.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">Psummary tables</span><br /><br />OK, "summaries" then.<br /><br />The static nature of data warehouse data allows the results of some frequently executed queries to be pre-computed and cached as summary tables. These are often created through the Oracle materialized view object type, although the use of an MV is not mandatory.<br /><br />The query rewrite function of the cost-based optimizer can use the metadata stored in materialized view definitions or through declarations of query equivalence made through the DBMS_ADVANCED_REWRITE package (10g+ only) to redirect queries against large base tables (typically data warehouse fact tables) to the smaller summary tables. In most cases the summary table does not have to be an exact match for the query.<br /><br />The major challenge in using summary tables is in finding an efficient mechanism for maintaining consistency between the summary and its base table(s).<br /><br />The major benefit is that almost any end-user query can be executed <span style="font-style: italic;">extremely</span> quickly with the correct use of summary tables.<br /><br /><span style="font-weight: bold; font-style: italic;"><br />PSummary</span><br /><br /><ul> <li>Partitioning allows efficient access to relatively large subsets of data and efficient bulk manipulation of data.</li> <li>Parallelism allows the work of a single user process to be shared among multiple slave processes, leading to faster completion time but higher resource usage.</li> <li>Psummaries provide extremely fast performance, but their maintenance and monitoring can require non-trivial efforts.</li> </ul> Now, hopefully these thoughts will leave my head alone.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1147964467653797112006-05-18T06:00:00.000-06:002006-05-18T13:11:49.956-06:00Strange Thing To CarryMy kids (3, 4 & 6) intercepted and detained a pedestrian passing our house the other evening on the grounds that he was in Public Possession of Dogs, and they needed to subject him to the usual line of questioning: "Names?", "Ages?", "Boys or Girls?", "Do they bite?" etc..<br /><br />Strangely none of them noticed what I saw immediately, which was the holstered handgun on his hip. I'm sure he had a license to do so, but what he was expecting might happen to him in our Nice Suburban Neighborhood is anyone's guess.<br /><br />On the other hand one of my wife's co-workers reported a sighting of a <a href="http://home.globalcrossing.net/%7Ebrendel/puma.html">mountain lion</a> about two miles southeast of us a couple of years ago. I'm inclined to wonder whether *ahem* alcohol was a factor in that case because we're definitely on the wrong side of the city for that kind of wildlife -- antelope, deer, foxes and the occasional coyote maybe, but how a lion would pass unnoticed around <a href="http://home.globalcrossing.net/%7Ebrendel/puma.html">Colorado Springs</a> from the mountains on the west to the plains on the eastern side is a mystery to me.<br /><br />However the mountains to the west of us aparantly have the highest density of mountain lions throughout the Rockies, which leads to some <a href="http://www.7522.com/page.php?code=34">basic precautions</a> when hiking with the kids -- don't let them straggle or walk too far in front is all it really amounts to. (That link contains other interesting information on bubonic plague, hanta virus, avalanches etc. by the way). Sightings and other <a href="http://www.denverpost.com/news/ci_3716178">less fortunate encounters</a> seem to be <a href="http://denver.yourhub.com/Story.aspx?contentid=85477">pretty common</a> up around Boulder though.<br /><br />Here's a prime example of the kind of plump, tender morsel that a lion would enjoy most.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/8036/953/1600/DSC02479_sml.jpg"><img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/8036/953/320/DSC02479_sml.jpg" alt="" border="0" /></a><br /><br />It's amazing how fast those legs will carry him if he's told that there's a lion behind him!David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1147369360155227002006-05-11T11:14:00.000-06:002006-05-11T11:48:27.986-06:00Getting the (Sub)Partition Name for a RowAdapted from a response to a question posted on Oracle-l, here are three methods for finding out what partition or subpartition a table row is stored in, or which partition or subpartition a row will be stored in.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">Logical Inference</span><br /><br />For range-based or list-based partitioning or for range-list composite partitioning it is often feasible to infer the partition or subpartition name from the values of the partition and subpartition key columns, as long as a sensible partition naming convention has been chosen.<br /><br />For example, for a range partitioned table defined in part by ...<br /><br /><pre>Create table T (col1 date ...)<br />Partition By Range (col1)<br />(<br />Partition Y2006_M01 values less than (date '2006-02-01'),<br />Partition Y2006_M02 values less than (date '2006-03-01'),<br />Partition Y2006_M03 values less than (date '2006-04-01'),<br />...<br />)</pre><br /><br />...we can use a SQL function to provide the partition name:<br /><br /><pre>To_Char(col1,'"Y"YYYY"_M"MM')</pre><br /><br />Note the use of double-quotes in the above formula to identify literal strings in the date format.<br /><br />This is a fast and simple method, although an historically varying granularity on the partitions or a complex partitioning scheme could make it difficult to maintain.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">DBMS_MView.PMarker</span><br /><br />In cases where it is difficult or impossible to do perform the logical inference (hash partitioning, for example, or with complex multicolumn range/list partitioning) there are a couple of other techniques that you can use.<br /><br />In the DBMS_MVIEW package there is a PMARKER function that returns the data_object_id for the object in which the row resides, and you can join to user/dba/all_objects using that.<br /><br />Here's a funky example script using variable numbers of hash subpartitions ...<br /><br /><pre>drop table t<br />/<br /><br />create table t (col1 , col2 , col3 )<br />partition by range (col1)<br />subpartition by hash (col2)<br />(<br />partition p1 values less than (2) subpartitions 2,<br />partition p2 values less than (3) subpartitions 4,<br />partition p3 values less than (4) subpartitions 8<br />)<br />as<br />select mod(rownum,3)+1,<br /> floor(dbms_random.value(1,256)),<br /> floor(dbms_random.value(1,10))<br />from all_objects<br />where rownum < 101<br />/<br /><br />with obj as<br /> (select --+ materialize<br /> data_object_id,<br /> subobject_name<br /> from user_objects<br /> where object_name = 'T' and<br /> object_type = 'TABLE SUBPARTITION')<br />select subobject_name,<br /> col3<br />from T,<br /> obj<br />where data_object_id = DBMS_MView.PMarker(t.rowid)<br />order by 1<br />/</pre><br /><br />My unsubstantiated guess is that this uses the file#/block# of the rowid to perform a look-up on the extent that contains the row. It therefore also ought to be possible to "hand-roll" a similar method based on extracting the file# and block# from the rowid's and joining to the dba/user/all_extents view (or a materialized subset of it, for performance reasons) to get the segment properties. I don't know if I'd care to go that route myself.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">TBL$OR$IDX$PART$NUM()</span><br /><br />The TBL$OR$IDX$PART$NUM() function gives you the appropriate partition number for a table value or set of values. It's an undocumented (except through metalink, if that counts) function with a couple of magic numbers in it, but the general format to use is ...<br /><br /><pre>TBL$OR$IDX$PART$NUM("PARTITIONED_TABLE_NAME", 0, d#, p#, "COLUMN_NAME")</pre><br /><br />The easiest way to get the appropriate format and magic numbers to use for this function is to run a trace on a "with validation" partition exchange against the table of interest, and you'll pretty much get the complete SQL that you need.<br /><br />So you might end up with something similar to ...<br /><br /><pre>with utp as<br /> (select --+ materialize<br /> partition_position,<br /> partition_name<br /> from user_tab_partitions<br /> where table_name = 'MY_TABLE')<br />select utp.partition_name,<br /> last_name,<br /> first_name<br />from my_table,<br /> utp<br />where utp.partition_position = TBL$OR$IDX$PART$NUM("MY_TABLE", 0, 0,<br />65535, "PART_COL")<br />/</pre><br /><br />This method has the advantage that you can just supply it with arbitrary values for the partition key column(s) and you will get the appropriate partition number/name. Therefore you can use it to answer the question "Which partitions will these rows go into?". If you use partition exchanges "without validation" then you can also use it to run periodic checks on whether your ETL process has been putting rows in the wrong partitions.<br /><br />The disadvantage is that it is undocumented and has those pesky magic numbers, or course.<br /><br /><br /><span style="font-weight: bold; font-style: italic;">Summary</span><br /><br />My preference is to use the method of logical inference, if possible.<br /><br />The other two are evidently based on very different methodologies -- one being based on the physical location of the row and the other on values of the partition key column(s), so they can be applied to different situations. The TBL$OR$IDX$PART$NUM method is rather more amenable to performance tuning by pre-aggregating the table data based on distinct partition keys prior to applying the function call.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146670122894085312006-05-03T09:28:00.000-06:002006-05-03T09:28:42.936-06:00Machine MusicOooh, this is nice.<br /><br />http://video.google.com/videoplay?docid=-5503582578132361295David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146489806002011132006-05-01T06:39:00.000-06:002006-05-01T07:23:29.186-06:00A Day Without ImmigrantsSo today is apparantly "<a href="http://www.cnn.com/2006/US/05/01/immigrant.day/index.html">A Day Without Immigrants</a>" and I just realised that this means me as well, technically speaking. Does it not seem strange that so immigrants should be held to be the source of so many problems in America, of all countries? And people in the southern border lands appear to be particularly prone to that finger-pointing, when they are living on land that was originally part of a Mexico too weakened by its own war for independence to be able to defend it from the young states to the north.<br /><br />I'm coming up to the eighth anniversary of my "stepping off the boat" as it were -- it's easy to work out as I just add on one year and a couple of days to my wedding anniversary, which is how long it took for my permanent resident visa to come through, plus a couple of weeks to get the last things packed and get a flight. I missed my first wedding anniversary by just five days I think. From the visa (and later job) interview questions I was asked I was apparantly suspected of being an economic migrant, which made the enormous paycut that I took to move from London, UK to Dayton, Ohio rather ironic.<br /><br />On the other hand, I don't really think of myself as an immigrant. I'm think I'm really someone who is just hanging out here for a while ... seeing the sights, doing a bit of shopping, being married, having kids etc.. On the other hand I've only been back to England once in all that time, for my brother's wedding in Cambridge last year. With my parents living in Spain and my parents-in-law living near Rome we tend to pay fleeting visits to Heathrow every now and then just to see if they've finished building it yet (which they haven't) and to stock-up on the few goodies that are available there and not from our local Fine Imported Goods emporium -- ie. the commissary at Peterson AFB. They sell Flakes, Crunchies, Milk Chocolate Hobnobs etc, although they fly off the shelves because everyone panic-buys them apparantly.<br /><br />So anyway I get itchy feet everytime I see Oracle blogsters writing of their travels, and we're regularly overcome by an urge to move back to Europe. Any part of it at all will do. We were recently thwarted in an attempted move to Slovenia or Romania, and now we're trying for Germany. My brother tells me we should be moving to Denmark -- in fact a friend of a friend ended up there after some kind of incident involving rowing to Iceland in a replica of a Viking longboat, during which voyage he apparantly had an affair with the wife of the group leader which must have involved either extraordinary levels of discretion or some extraordinarily tense mealtimes -- but frankly it's probably Hobson's choice where we land. If the USAF doesn't have positions for a Developmental Engineer at least <span style="font-style: italic;">available</span> then it's not on the list.<br /><br />So where was I?<br /><br />Ah yes, the immigrant day thing. Well it turns out that most of my work colleagues will be in a Customer Acceptance Test for most of the day so they wouldn't notice me not being here (here being 1,200 miles from them) anyway. However, I applaud the priniciple and I may go down the Monica's Taco Shop for a breakfast burrito to show support for the cause.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146319855356400652006-04-29T08:10:00.000-06:002006-04-29T08:10:55.356-06:00WelcomeWelcome to the Dark Side, <a href="http://markmal.blogspot.com/">Mark</a>!David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146200108277136432006-04-27T22:47:00.000-06:002006-04-27T22:57:23.803-06:00Whoops, security breach.Well it turns out that thanks to "Homeland Security" your complete driver's license information may be on the Internet ... although the good news is that you can get it taken off. It seemed like <span style="font-style: italic;">such</span> a good idea that I've taken mine off.<br /><br />Go <a href="http://www.license.shorturl.com/">here</a>, search for it, and go through the "Hide my Records" procedure if it's there. What is wrong with these people?<br /><br />I already checked for George Bush of Texas, but I suppose there's a few of them and the "real" one isn't listed. If you're quick though (ie. quicker than him) you can get yourself a copy of the license of Mr Thomas Kyte of Leesburg, Virginia before he gets the records removed ... that's quite the photo!David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146069177848561082006-04-26T10:28:00.000-06:002006-04-26T10:32:57.913-06:00A Dose of StupidityNatural selection is a fine thing, but when a person's stupidity and arrogance takes someone else's life we can only hope that there will be some serious repurcussions.<br /><br />http://www.kcsg.com/story.aspx?id=682<br /><br />No helmet, no protective gear, and 85mph in a 35mph zone on a new machine? At the very least I hope this guy got skinned well enough that he'll need a helmet to get women to look at him in future.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1146059181406966762006-04-26T07:44:00.000-06:002006-04-26T07:46:21.440-06:00More Security For You Sir.http://www.computerworld.com/securitytopics/security/story/0,10801,110880,00.html<br /><br />Looks like some kind of security administrator role being introduced. $20,000 per CPU or $400 per user seems a littlesteep to me though.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1145456280429773772006-04-19T08:00:00.000-06:002006-04-19T08:58:25.350-06:00Soon Time to Move AgainIt's that time again, when the wife and I have to fill in forms and wishlists to try and influence our next posting. Last time we got pretty lucky - Colorado Springs wasn't on our list but it turned out pretty well.<br /><br />The eternal problem is that wherever there are Air Force bases, all commerce other than the defence industry tends to flee. It's a trend that is continuing, accelerating even, with the consolidation of Air Force units into the larger bases with plenty of room for growth -- ie. in the middle of a God-forsaken wilderness with a 60 mile commute to the nearest habitation.<br /><br />That isn't to say that they aren't good places to live -- <a href="http://maps.google.com/maps?f=q&hl=en&amp;q=eglin+afb&ll=30.616131,-86.306165&spn=0.856828,1.733093&t=h&om=1">Eglin AFB</a> in Florida is next to one of the best beaches in the world, and <a href="http://maps.google.com/maps?f=q&hl=en&amp;q=eglin+afb&ll=30.616131,-86.306165&spn=0.856828,1.733093&t=h&om=1">Vandenburg AFB</a> is nicely positioned on the California coast. Still they are not exactly major centres of commercial high-tech activity. In Colorado Springs I landed on my feet with a work-at-home contract with a longterm client, but that sort of thing wears thin after a while. Pretty quickly actually, especially in conjunction with a move to a new town.<br /><br />The current hot prospect looks like <a href="http://maps.google.com/maps?f=q&hl=en&q=hanscom+afb&ll=42.459191,-71.272465&spn=0.367266,0.866547&om=1">Hanscom AFB</a>, just outside Boston, or maybe the Pentagon. I think I like the idea of Boston more. Actually I like the idea of Europe even more than that, with some interesting vacancies at <a href="http://www.viamichelin.com/viamichelin/gbr/dyn/controller/mapPerformPage?pim=true&act=RefineToMap&rnd=1145458184360&E_mg=210506110lS20J106109164947913616MAPB2C1a103gbr542000130u1103240000bcmFtc3RlaW400001100&stat=ambiguous_map&strChoice=0">Ramstein</a> to the south-west of Frankfurt -- I'll have to brush up on the non-existant German that I didn't learn from either the Turks I worked with in Munich or the girlfriend from Manchester I was living with at the time.<br /><br />Early days yet though, and the whole process just epitomises the story of the best-laid plans of mice and men often going astray. If the worst comes to the worst and we do end up in the middle of nowhere then I'll be hoping for at least some nearby reasonable-sized airport, and I'll do the road-warrior thing for a few years. Or we'll just find the wife a new employer who doesn't unreasonably insist on moving it's employees every three years or so, regardless of the diverse other opportunities in the area. Tut! Maybe we'll move to New Zealand instead.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1145385323134184782006-04-18T12:21:00.000-06:002006-04-18T12:35:23.180-06:00Space Requirement for Compressed Row UpdatesIt seems that when you update rows within compressed blocks the data is temporarily decompressed then recompressed, possibly causing the table to grow.<br /><br />Here I create an uncompressed copy of DBA_OBJECTS, which takes 788 blocks to store. The compressed copy is then shown to take 256 blocks.<br /><br />On updating all of the rows the table has grown to 1038 blocks, approximately 256+788, yet as the DBMS_ROWID-based queries show the rows have not moved. It seems that an additional approximately-788 blocks of space have been added to move the table's high water mark.<br /><br />Curioser and curioser.<br /><br /><br /><pre>SQL> drop table t1<br /> 2 <br /><br />Table dropped.<br /><br />SQL><br />SQL> create table t1<br /> 2 nocompress<br /> 3 pctfree 0<br /> 4 as<br /> 5 select * from dba_objects<br /> 6 /<br /><br />Table created.<br /><br />SQL><br />SQL> exec dbms_stats.gather_table_stats(user,'T1')<br /><br />PL/SQL procedure successfully completed.<br /><br />SQL><br />SQL> select blocks,empty_blocks from user_tables<br /> 2 where table_name ='T1'<br /> 3 /<br /><br /> BLOCKS EMPTY_BLOCKS<br />---------- ------------<br /> 788 0<br /><br />SQL><br />SQL> select min(dbms_rowid.rowid_block_number(rowid)) min_block,<br /> 2 max(dbms_rowid.rowid_block_number(rowid)) max_block,<br /> 3 count(distinct dbms_rowid.rowid_block_number(rowid)) num_blocks<br /> 4 from t1<br /> 5 /<br /><br />MIN_BLOCK MAX_BLOCK NUM_BLOCKS<br />---------- ---------- ----------<br /> 1610346 1611133 788<br /><br />SQL><br />SQL> update t1 set owner = rtrim(owner)<br /> 2 /<br /><br />60120 rows updated.<br /><br />SQL> commit<br /> 2 /<br /><br />Commit complete.<br /><br />SQL><br />SQL> exec dbms_stats.gather_table_stats(user,'T1')<br /><br />PL/SQL procedure successfully completed.<br /><br />SQL><br />SQL> select blocks,empty_blocks from user_tables<br /> 2 where table_name ='T1'<br /> 3 /<br /><br /> BLOCKS EMPTY_BLOCKS<br />---------- ------------<br /> 788 0<br /><br />SQL> select min(dbms_rowid.rowid_block_number(rowid)) min_block,<br /> 2 max(dbms_rowid.rowid_block_number(rowid)) max_block,<br /> 3 count(distinct dbms_rowid.rowid_block_number(rowid)) num_blocks<br /> 4 from t1<br /> 5 /<br /><br />MIN_BLOCK MAX_BLOCK NUM_BLOCKS<br />---------- ---------- ----------<br /> 1610346 1611133 788<br /><br />SQL><br />SQL> drop table t1<br /> 2 /<br /><br />Table dropped.<br /><br />SQL><br />SQL> create table t1<br /> 2 compress<br /> 3 pctfree 0<br /> 4 as<br /> 5 select * from dba_objects<br /> 6 /<br /><br />Table created.<br /><br />SQL><br />SQL> exec dbms_stats.gather_table_stats(user,'T1')<br /><br />PL/SQL procedure successfully completed.<br /><br />SQL><br />SQL> select blocks,empty_blocks from user_tables<br /> 2 where table_name ='T1'<br /> 3 /<br /><br /> BLOCKS EMPTY_BLOCKS<br />---------- ------------<br /> 256 0<br /><br />SQL> select min(dbms_rowid.rowid_block_number(rowid)) min_block,<br /> 2 max(dbms_rowid.rowid_block_number(rowid)) max_block,<br /> 3 count(distinct dbms_rowid.rowid_block_number(rowid)) num_blocks<br /> 4 from t1<br /> 5 /<br /><br />MIN_BLOCK MAX_BLOCK NUM_BLOCKS<br />---------- ---------- ----------<br /> 1611146 1611401 256<br /><br />SQL><br />SQL> update t1 set owner = rtrim(owner)<br /> 2 /<br /><br />60121 rows updated.<br /><br />SQL> commit<br /> 2 /<br /><br />Commit complete.<br /><br />SQL><br />SQL> exec dbms_stats.gather_table_stats(user,'T1')<br /><br />PL/SQL procedure successfully completed.<br /><br />SQL><br />SQL> select blocks,empty_blocks from user_tables<br /> 2 where table_name ='T1'<br /> 3 /<br /><br /> BLOCKS EMPTY_BLOCKS<br />---------- ------------<br /> 1038 0<br /><br />SQL> select min(dbms_rowid.rowid_block_number(rowid)) min_block,<br /> 2 max(dbms_rowid.rowid_block_number(rowid)) max_block,<br /> 3 count(distinct dbms_rowid.rowid_block_number(rowid)) num_blocks<br /> 4 from t1<br /> 5 /<br /><br />MIN_BLOCK MAX_BLOCK NUM_BLOCKS<br />---------- ---------- ----------<br /> 1611146 1611401 256<br /><br />SQL> update t1 set owner = lower(owner)<br /> 2 /<br /><br />60121 rows updated.<br /><br />SQL> commit<br /> 2 /<br /><br />Commit complete.<br /><br />SQL> exec dbms_stats.gather_table_stats(user,'T1')<br /><br />PL/SQL procedure successfully completed.<br /><br />SQL><br />SQL> select blocks,empty_blocks from user_tables<br /> 2 where table_name ='T1'<br /> 3 /<br /><br /> BLOCKS EMPTY_BLOCKS<br />---------- ------------<br /> 1038 0<br /><br />SQL> select min(dbms_rowid.rowid_block_number(rowid)) min_block,<br /> 2 max(dbms_rowid.rowid_block_number(rowid)) max_block,<br /> 3 count(distinct dbms_rowid.rowid_block_number(rowid)) num_blocks<br /> 4 from t1<br /> 5 /<br /><br />MIN_BLOCK MAX_BLOCK NUM_BLOCKS<br />---------- ---------- ----------<br /> 1611146 1611401 256</pre>David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1145372090229188162006-04-18T08:38:00.000-06:002006-04-18T08:54:50.263-06:00Introspection timeI wandered over to <a href="http://www.similarminds.com/index.html">Similar Minds</a> to try their <a href="http://similarminds.com/jung.html">Jung personality test</a>.<br /><br /><div align="center"><!--63.33 52.38 66.67 65.71--> <table bg="" style="color: rgb(221, 221, 221);" border="0" cellpadding="0" cellspacing="0"> <tbody><tr> <td width="250"> <div align="center"> <span style="color:black;"><b><a href="http://similarminds.com/jung/istp.html">ISTP</a></b> - "Engineer". Values freedom of action and following interests and impulses. Independent, concise in speech, master of tools. 5.4% of total population. </span></div> </td> </tr> </tbody></table> <a href="http://similarminds.com/">Free Jung Personality Test (similar to Myers-Briggs/MBTI)</a></div><br /><br />Apparantly it means <a href="http://www.personalitypage.com/ISTP.html">this</a>. some of those observations seem to be pretty spot-on -- ie. the one's that reflect well on me. Just ignore all the others, they're not true. Also the "athletic" thing, pay no attention to that.<br /><br />Careerwise I seem to be doing OK. Here are some suggestions from the website:<br /><ol> <li>Police and Detective Work</li> <li>Forensic Pathologists</li> <li>Computer Programmers, System Analysts and Computer Specialists</li> <li>Engineers</li> <li>Carpenters</li> <li>Mechanics</li> <li>Pilots, Drivers, Motorcyclists</li> <li>Athletes</li> <li>Entrepreneurs</li> </ol> Well, #3 there is obviously on target ... I also built a very nice fence and gate, and next I'm putting up some trellises so that's #5 ... I have a Masters degree in Aeronautical Engineering and an <a href="http://en.wikipedia.org/wiki/Higher_National_Certificate">HNC</a> in <a href="http://www.warsashcentre.co.uk/">Marine Engineering</a>, so that's #4 ... I ride a 2005 Triumph Tiger, #7. I really ought to work harder on #8 though.<br /><br />OK, back to work people.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1145237105044518662006-04-16T19:12:00.000-06:002006-04-16T19:25:05.086-06:00Bad FormI just finished filling in the thirteen-pages of forms required to transfer Number Three Son to a new day care. Here are some statistics on the number of times the forms required particular information<br /><ul> <li>His name: Seven</li> <li>His date of birth: Four</li> <li>His current age: Two</li> <li>His doctor's name: Three<br /> </li> <li>My address: Seven</li> <li>My phone number: Ten<br /> </li> <li>My signature: <span style="font-style: italic; font-weight: bold;">Eighteen</span></li> </ul> Things I have now lost as a result:<br /><ul> <li>Use of my writing hand</li> <li>Memory of my social security number<br /> </li> <li>Last trace of sympathy for de-normalisation for performance</li> </ul> And my will to live is fading fast ... there must be a beer around here somewhere ...David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144956738357120412006-04-13T07:00:00.000-06:002006-04-13T13:44:20.116-06:00In Praise of ISO 8601As a UK ex-patriate and US resident I'm very sensitive to date formats. Moving from the DD/MM/YYY format to the MM/DD/YYYY format was a traumatic experience, and after eight years I still get a nervous twitch when I need to place the month before the day. What kind of a twisted mind thought that up?<br /><br />Probably the same one who decided that in my first job in the US I'd be dealing with a system for which the preferred date display formats were to be YYDDD and YYYYDDD. There can't be many people who are instinctively aware that the first of October is day 274 of a non-leap year, but if you find someone who is then I can tell you who they work for. Furthermore, they may belive that this data format is known as the Julian Date, and they're wrong about that of course. Further-furthermore it's surprising how many database designers believe that a requirement to display a date in YYYYDDD format means that it is a great idea to store it as a NUMBER(7), leading to it being displayed by default in many tools as "2,006,274.00". Actually it's not surprising, it's just irritating for the hopefully-obvious reasons.<br /><br />The other exception to the adherence to the MM/DD/YYYY format was the Immigration Service, who seemed to prefer DD/MM/YYYY on their forms. Thus I was lulled into a false sense of security through the whole visa process, and only ambushed with the MM/DD/YYYY abomination when I was fully commited to the process.<br /><br />This is why I have such a liking for <a href="http://hydracen.com/dx/iso8601.htm">ISO 8601</a>, which specifies the standard date format to be YYYY-MM-DD, with a reduced precision option of YYYY-MM and an optional time component of what we Oracleers would represent as hh24:mi:ss. I could lay out a complete set of reasons why this makes more sense but it is done very well <a href="http://www.cl.cam.ac.uk/%7Emgk25/iso-time.html">here</a>, and the display of week numbers is also nicely handled.<br /><br />Now then, do you suppose that if the massed hordes of database developers and administrators rose up against the MM/DD/YYYY and the less-objectionable DD/MM/YYYY and DD-Mon-YYYY formats in favour of YYYY-MM-DD then we might make a meaningful impact on this scourge? I'd hope so. If we all started a "Movement Against Date Display Stupidity" (MADDS) by claiming that there was a fatal bug in the system when displaying anything other than YYYY-MM-DD then we might deceive our way to virtue, and all mankind would benefit.<br /><br />It'd do me a power of good, anyway.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144856174374678892006-04-12T07:00:00.000-06:002006-04-12T09:43:30.516-06:00A Quick Materialized View Performance NoteI was asked in an email this morning about how to improve materialized view refresh performance, and it's something that appears in Google hits for the blog quite frequently. So I thought I'd write a quick-and-dirty posting to summarise some of the research (and the resulting practical applications) that I've been fiddling with recently.<br /><br />Here are some bullet points:<br /><ol><li>The materialized view fast refresh mechanism is a one-size-fits-all solution, and is probably not efficient for 99% of summary table maintenance operations.</li><li>The join of the aggregated change data to the MV is function-based, as the columns of both relations are wrapped in the <a href="http://oraclesponge.blogspot.com/2005/11/optimizing-materialized-views-part-iii.html">Sys_Op_Map_NonNull</a>() function that allows "null = null" joins. I think that it is extremely unlikely that anyone has nullable attribute columns in their fact or summary tables, so this (and the composite function-based index required to support it) are a waste of resources.</li><li>Because of the nature of the join it seems to be extremely unlikely that <a href="http://www.blogger.com/posts.g?blogID=11995638">partition pruning</a> of the summary table could take place.</li><li>The join mechanism promotes nested loop joins, where a hash join is probably more efficient (that's technically an outer join in the merge, of course).<br /></li><li>The refresh mechanism assumes that a merge will be required, when sometimes an insert is not only possible but is very much more efficient.</li></ol>If performance (and robustness, IMHO) are an issue for you then I would advise that you do the following:<br /><ol><li>Use materialized views only for enabling query rewrite (which means creating them on a prebuilt summary table, and unless you are loading to the summary by partition exchange then you have to drop the MV, refresh the summary table, and recreate the MV). In 10g it is much more easy to use the <a href="http://download-west.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_advrwr.htm#i999507">DBMS_Advanced_Rewrite</a> package instead of MV's.</li><li>Write your own refresh code, based on the usual principles of writing good SQL. If you don't need a merge then <a href="http://oraclesponge.blogspot.com/2005/11/optimizing-materialized-views-part-iii.html">don't use it</a>. If you don't need to join to dimension tables to get higher attributes then don't do it.<br /></li><li>Leverage different levels of aggregation to help produce higher levels. For a series of hierarchical summaries, <a href="http://oraclesponge.blogspot.com/2005/12/optimizing-materialized-views-part-iv.html">multi-level aggregations</a> can be extremely beneficial.<br /></li><li>Consider storing the refresh and MV definition SQL in CLOB columns of a summary management table, so they can be tuned and edited without needing to open up package code to do so.</li><li>Consider using a complete refresh, either through MV's or manually, for higher aggregation levels, particularly when you can reference another summary table to do so.<br /></li></ol>My practical experience of taking this path delivered a reduction in the refresh time of a set of seven materialized views based on a single fact table, from a couple of hours down to six minutes. The publication of this is an example of what my client's technical lead calls "polishing the crown" :D<br /><br />Anyway, this is all a sort-of abstract from a whitepaper that I'm working on right now, which will include all sorts of proofs and demonstrations of the above, plus some process and risk management advice, but it doesn't look like it'll be ready very soon. Feel free to comment or ask questions on the points raised above though -- I don't want anyone to be kept in suspenders 'till the paper is finished.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144447118667544212006-04-07T15:37:00.000-06:002006-04-07T16:03:07.976-06:00My Dishwasher is List PartitionedMy dishwasher has two levels in it. The bottom level is for plates and Large Things, the top level is for cups and Small Things, and there is a removable cutlery partition attached to the door.<br /><br />If I had a spare cutlery partition then I could keep one of them in use by the dishwashing system while the other one is treated as a regular cutlery holder, and it could be filled with dirty cutlery as the items become available. When it was full I could perform a cutlery partition exchange between the one with clean items and the one now full of dirty items.<br /><br />If I had spare levels then they could be treated in a similar manner. I believe that commercial dishwashers have exactly that configuration, thus they operate with lower downtime because of this exchange mechanism, although the overall configuration requires more space.<br /><br />Within the cutlery partition there are six subpartitions. I like to fill each one with a single type of cutlery -- one for knives, two for spoons (they don't stack as well), a couple for forks, and one for other items. Although it is more work to separate the items into these subpartitions it has the advantage of physically clustering all the spoons together and I can access all items of one type without having to scan the complete cutlery partition.<br /><br />For the upper and lower levels similar principles apply, although they are not really subpartitioned in the same way. Instead the large plates are clustered in a single contiguous range -- the small plates, the glasses and the mugs each have their own place. Again it is more work to insert the items like this, but the advantage of faster retrieval is similar because I don't have to scan the complete level to pick similar items out from dissimilar ones. <br /><br />That is all.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144347330610410662006-04-06T11:53:00.000-06:002006-04-06T12:15:30.690-06:00The State of The SpongeI notice that the blog just passed it's 80,000 page load since I started using Statcounter to monitor it, and that's just one day short of its first anniversary so it's time for stats.<br /><br />Looking at the statistics for the last 1000 visits, one-third of them come from Google searches -- most seem to be to do with materialized views, oddly enough.<br /><br /><pre>186 www.google.com <br />77 tkyte.blogspot.com <br />23 www.google.co.uk <br />23 www.bloglines.com <br />20 oracledoug.blogspot.com <br />19 www.google.co.in <br />14 www.google.com.au <br />10 www.google.ca <br />9 www.google.fr <br />8 thinkoracle.blogspot.com <br />7 blogs.oracle.com <br />7 orawin.info <br />6 www.google.de <br />6 oradot.com <br />6 www.rittman.net <br />5 www.google.es <br />5 www.blogger.com <br />5 www.petefinnigan.com <br />4 my5.statcounter.com <br />4 www.google.be<br />4 www.google.it <br />4 search.blogger.com <br />4 www.newsgator.co.uk <br />4 www.netvibes.com <br />3 www.google.com.tr <br />3 www.google.fi <br />3 uk.my.yahoo.com <br />3 www.edpadgett.com <br />3 ora-dev.blogspot.com <br />3 search.msn.com <br />3 www.google.se <br />2 www.google.com.sg <br />2 www.google.co.il <br />2 www.oracle-base.com <br />2 www.google.ru <br />2 www.google.ro <br />2 www.google.ch <br />2 search.yahoo.com <br />2 pjs-random.blogspot.com <br />2 www.google.ie<br />2 bloglines.com <br />2 www.google.com.ph <br />2 www.google.nl <br />2 oracle-base.com <br />2 discuss.joelonsoftware.com <br />2 www.google.com.sg <br />1 blogsearch.google.com <br />1 www.dbasupport.com <br />1 my2.statcounter.com <br />1 oramossoracle.blogspot.com <br />1 www.nomad8.com <br />1 www.google.co.za <br />1 my.yahoo.com <br />1 www.google.com.tw <br />1 www.google.com.hk <br />1 www.google.pl <br />1 www.google.co.kr <br />1 tkyte-test.blogspot.com <br />1 www.google.is <br />1 www.google.cl<br />1 idyller.blogspot.com <br />1 www.google.com.ar <br />1 www.google.co.jp <br />1 peec2006.blogspot.com <br />1 www.google.com.br <br />1 www.google.gr <br />1 portal.umbrialistens.com <br />1 www.google.co.ve <br />1 kdsatplay.blogspot.com <br />1 www.google.dk <br />1 www.google.com.eg <br />1 oraqa.com <br />1 www.google.com.co <br />1 ambigramania.blogspot.com <br />1 www.google.pt <br />1 www.surfwax.com <br />1 www.google.com.mx <br />1 www.alltheweb.com</pre><br /><br />Fifty-two countries are represented, if we ignore the unknowns ...<br /><br /><pre>402 41.66% United States<br />132 13.68% United Kingdom<br />80 8.29% Canada<br />60 6.22% Lithuania<br />39 4.04% Netherlands<br />37 3.83% India<br />26 2.69% Australia<br />20 2.07% Germany<br />17 1.76% France<br />15 1.55% Switzerland<br />13 1.35% Spain<br />11 1.14% Unknown -<br />9 0.93% Russian Federation<br />8 0.83% Belgium<br />7 0.73% Turkey<br />7 0.73% Japan<br />6 0.62% Norway<br />6 0.62% Denmark<br />5 0.52% Portugal<br />4 0.41% United Arab Emirates<br />4 0.41% Italy<br />4 0.41% Sweden<br />4 0.41% Israel<br />3 0.31% Colombia<br />3 0.31% Greece<br />3 0.31% Singapore<br />2 0.21% Romania<br />2 0.21% Philippines<br />2 0.21% Poland<br />2 0.21% Austria<br />2 0.21% Ireland<br />2 0.21% Serbia And Montenegro<br />2 0.21% Finland<br />2 0.21% Latvia<br />2 0.21% Bolivia<br />2 0.21% Uruguay<br />2 0.21% Argentina<br />2 0.21% South Africa<br />2 0.21% Puerto Rico<br />1 0.10% Pakistan<br />1 0.10% Bulgaria<br />1 0.10% Estonia<br />1 0.10% Kenya<br />1 0.10% Chile<br />1 0.10% Andorra<br />1 0.10% Ukraine<br />1 0.10% Iceland<br />1 0.10% New Zealand<br />1 0.10% Egypt<br />1 0.10% Brazil<br />1 0.10% Slovenia<br />1 0.10% Korea, Republic Of<br />1 0.10% Hong Kong</pre><br /><br />Good to see the Netherlands up there this time! Readership seems to be up to 13 Dutch people, unless some of them are cheating and using multiple computers.<br /><br />The most frequently occuring city for Sponge readers is London, UK, then Calgary, Ontario, Arlington, Nieuwegein ...<br /><br />The most popular article is "Writing Good SQL". It's a perennial favourite with the Google crowd.<br /><br />That's all -- back to work people!David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144332773424151602006-04-06T08:12:00.000-06:002006-04-06T08:12:53.510-06:00A Story of Database FUDThe sorry tale here ... http://discuss.joelonsoftware.com/default.asp?joel.3.328948.11David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144273645992901022006-04-05T15:30:00.000-06:002006-04-05T15:47:26.070-06:00Bad Advice On Materialized View Deferrable ConstraintsAn <a href="http://www.jlcomp.demon.co.uk/MV_non_bug.html">article</a> by Jonathan Lewis on constraint problems with materialized views set off a little bell in my head about a metalink document on the subject, <a href="https://metalink.oracle.com/metalink/plsql/ml2_documents.showFrameDocument?p_database_id=NOT&p_id=284101.1">Note 284101.1</a>.<br /><br />The note protests the use of unique, foreign key and primary key constraints on materialized views, and includes the following interesting phrases ...<br /><br />"<em>It is not a good idea to create unique (unique indexes ) constraints , primary key or Foreign key constraints on the snapshot base table ... There should not be any Unique/PK constraints at Mview base table ... Drop the Unique/PK constriants on Mview Base Tables</em>."<br /><br />Then one of the workarounds is "<em>You can have Deferred Constraints</em>". The document doesn't identify why having deferred constraints might be a bad idea, or why not having integrity constraints on the table at all is preferable to having them deferred .. I can't think of a reason why that might be so, and I can think of several reasons why it might not be so (query optimization being the prime one).<br /><br />All this misdirection and ambiguity, combined with the abbreviation of an error code from "ORA-00001" to "ORA-1" in the title of a help document (does that make sense to anyone?) make this a pretty poor piece of work. It's not the <a href="http://oraclesponge.blogspot.com/2005/06/most-useless-metalink-article-ever.html">Most Useless Metalink Article Ever</a>, but it's close.<br /><br />By the way, if you read the title and the first few words of this article, and thought "Dave's going to say that Jonathan Lewis gave bad advice!" before realising I wasn't ... the effect was intentional :D If you didn't think that then my plan failed.David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144243454759339092006-04-05T07:16:00.000-06:002006-04-05T07:24:18.296-06:00What's Wrong With Opera?Not the musical form, obviously there's nothing wrong with that at all.<br /><br />The browser is very nice, but I can't read the Oracle forums with it. If I go <a href="http://forums.oracle.com/forums/forum.jspa?forumID=260">here</a> then clicking on any link takes me <a href="http://www.oracle.com/errors/404.html">here</a>. Opera also doesn't display the little images that are scattered all around the page, and I get a bunch of rectangles with text in them. Internet Explorer doesn't have this problem, nor the issues that I wrote about in Firefox the other day (heresy, I know).<br /><br />Why is reading HTML and following links so difficult? You'd imagine that they'd have it close to working by now. Well, maybe there's some configuration thing that needs to be done to the browser, but I'm not sure why I should have to spend my time messing about with this kind of crap.<br /><br />OK, I promise to write something later this week about a technology that I do like. Um ....David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144199809171325732006-04-04T19:15:00.000-06:002006-04-04T19:16:49.210-06:00Development and TuningI had a pithy thought earlier today.<br /><br />1. Development is the business of making the database do work<br />2. Tuning is the business of reducing the amount of work the database does.<br /><br />Therefore, tuning is the opposite of development. It is "anti-development"!David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.comtag:blogger.com,1999:blog-11995638.post-1144076377871260612006-04-03T08:49:00.000-06:002006-04-03T08:59:37.916-06:00What's Wrong With Firefox?A number of things.<br /><br /><ol><li>On one of my machines it consistently refuses to open particular web sites. <a href="http://www.dbdebunk.com/index.html">http://www.dbdebunk.com/index.html</a> is one of them -- IE has no problem, Opera has no problem. No error message, nothing. It just seems to pretend that I haven't asked it do do anything.</li><li>It's a resource hog. Memory usage often tops 150Mb, and can only be reduced by stopping and restarting it. If my machine startys running slowly then I know where to look -- Firefox is sitting and chewing up CPU cycles to no apparant effect.</li><li>It's unstable. I generally get four or five crashes a week, and they're not associated with having a lot of windows or tabs open either.</li></ol><p>It didn't used to be this bad, and it seems to be getting worse. AdBlock has been the only reason to keep using it, but that's not enough anymore. I'd actually rather have adverts on the page than put up with the all of Firefox's crap .</p><p> </p>David Aldridgehttp://www.blogger.com/profile/12440658753245953038noreply@blogger.com