Tuesday 19 January 2010

Salesforce and force.com

I like salesforce.com and force.com. Both I think are real pioneers in the terra-incognita, or maybe I should call it the nimbus-incognita, which is called the "Cloud-platform". Both are very easy to use SaaS (Software as a Service) platforms. The applications are based on solid data modelling principles and the back-end relational database used is a massive parallel implementation of Oracle databases around the world. You can check their systems availability and the number of transactions done per day here trust.salesforce.com.

Although salesforce insists that their applications are stored in objects which are not "just database tables", their first step in creating an application involves capturing the data model. This is really a very "database" platform.

The platform offers a solid 2x2=4 environment to build and host applications and all work is done with a browser. That is, their IDE is the browser. They even provide you with a sandbox for your unit tests and and Eclipse plug-in for code access to the platform. The IDE is shared between their CRM platform salesforce.com and their developer platform force.com. In the salesforce.com platform you are able to extend a complete and very well designed CRM data model to include anything you wish. In the force.com platform you can create applications from scratch about anything! Among the two, force.com is what impressed me the most and made me to write this blog post. There is not much to be done in the salesforce.com platform, as is a complete working CRM application in itself which would suit any size company which needs a good CRM system.

Force.com on the other hand is a blank canvas. As long as you now what you want, you can start building it straight away. You start with the data model, then you determine your objects, and their relationships and once you have layered your data model in your system, the platform straight away provides you with the means to update and insert records in the back-end database. It automatically builds forms and reports. It also provides you with work-flow and automatic callendaring and emailing functions. Plus, it has a coding language called Apex, which is Java like with classes and triggers enabling you to enhance your application logic. It also has a very HTML like markup language called Visualforce. If you want to migrate your legacy data into the platform you should look at cloud ready ETL and data integration tools like Informatica (£££) and Talend Open Studio  (free).

A project I recently have done in Kizoom using this platform which took me 82 hours that is 10 days approximately to complete. The project was migrating all data and application logic from a legacy database system to force.com. During my work, data integration tools like Informatica and Talend helped me to move the data quickly into the force.com data model, and the already built in features of force.com provided me data entry forms and advanced reports. Because all this is in the cloud I was able to easily utilise geolocation with Google Maps API. The legacy system was a Microsoft SQL Server online database of fault records of computers in publicly available street kiosks around UK. Force.com made the application available in the cloud which meant the UK-wide field engineers of the company were able to easily login and access it on the road without having to use the company network (VPN) but just the cloud.

Below is a snapshot of the app.






Conclusion

The platform is very capable, easy to use and very intuitive. It has tremendous potential and achieves good economics in the development efforts. One shouldn't be shy to use it.


Monday 4 January 2010

SQL Tuning Advisor and SQL Access Advisor in Oracle 10g

Oracle 10g with its AWR (Automatic Workload Repository) for automatic collection of performance statistics and with ADDM (Automatic Database Diagnostic Monitor) for identifying root causes of problems, is a self-healing and self-tuning getting wiser every day and very soon will start to think on its own database.

There are features in Oracle 10g which help you to quickly find out what is wrong with the database. Features like ASH (Active Session History) to peak into what your active sessions are waiting for and Server Generated Alerts with Metrics and Thresholds are all tools which tell you what is really going on in your database. The OEM (Oracle Enterprise Manager) Database control is a brilliant interface you can use to learn and find out more about all these smart enhancements. All in the name of pro-active database management.

What is database well-being all about anyway? Isn't it high throughput(OLTP) and response time(DSS)? Aren't all databases working to achieve these?

Oracle 10g has also an Advisory Framework which based on workload, will also try to advise you on configuration issues like Buffer Cache, Library Cache, PGA, Undo and Segments used. There are also Tuning-Related Advisors which deal with SQL Tuning and these are:

I - SQL Tuning Advisor
II - SQL Access Advisor

In this post I will try to explain the usage of these two advisors in the job of tuning bad and nasty SQL statements.

All automation is good, self healing databases are very good. But what happens in the development arena when a developer turns up to your desk pointing to an email he/she just sent to you and says '...what's wrong with this SQL statement? it takes ages? Why is Oracle so slow?...' I am particularly fond of the last comment.

How can we quickly look at what is wrong with the SQL statement using the SQL Tuning Advisor? Here is how.

I - SQL Tuning Advisor

Using the DBMS_SQLTUNE package to tune SQL

Assuming the suspect query is something like "SELECT * FROM SESSIONS, SOURCE_EVENTS", two very large tables, and your schema has the ADVISOR privilege granted, you would put this query into the Oracle SQL Tuning Advisor engine using the PL/SQL package DBMS_SQLTUNE like this:

1. Create the tuning task

In SQL*Plus and in the schema where objects live, use the procedure dbms_sqltune.create_tuning_task to create a tuning task.

SQL>
declare tname varchar2(30);
begin
tname := dbms_sqltune.create_tuning_task(sql_text=>'select * from sessions, source_events');
end;
/

PL/SQL procedure successfully completed.

Then you can check to make sure that your task is created and get the TASK_NAME value as you will need this in the next step. I could name the task, just being lazy...

SQL> select task_name from user_advisor_log;

TASK_NAME
------------------------------
TASK_51415


2. Execute the tuning tasks

Execute the tuning task you created in step 1 with the procedure dbms_sqltune.execute_tuning_task

SQL> exec dbms_sqltune.execute_tuning_task('TASK_51415');



3. Get the tuning report

Get the tuning report/recommendation with the following SQL.

SQL> set long 50000
SQL> select dbms_sqltune.report_tuning_task('TASK_51415') from dual;


DBMS_SQLTUNE.REPORT_TUNING_TASK('TASK_51415')

(CLOB) GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : TASK_51415
Tuning Task Owner : ACHILLES
Scope : COMPREHENSIVE
Time Limit(seconds) : 1800
Completion Status : COMPLETED
Started at : 12/20/2009 18:44:05
Completed at : 12/20/2009 18:44:14
Number of SQL Restructure Findings: 1

-------------------------------------------------------------------------------
Schema Name: ACHILLES
SQL ID : 8qsdf0a6qv4g7
SQL Text : select * from sessions, source_events

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- Restructure SQL finding (see plan 1 in explain plans section)
----------------------------------------------------------------
An expensive cartesian product operation was found at line ID 3 of the
execution plan.

Recommendation
--------------
- Consider removing the disconnected table or view from this statement or
add a join condition which refers to it.

Rationale
---------
A cartesian product should be avoided whenever possible because it is an
expensive operation and might produce a large amount of data.

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

1- Original
-----------
Plan hash value: 3883039950

---------------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop | TQ |IN-OUT| PQ Distrib |
---------------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 33T| 4158T| 4367M (2)|999:59:59 | | | | | |
| 1 | PX COORDINATOR | | | | | | | | | | |
| 2 | PX SEND QC (RANDOM) | :TQ10001 | 33T| 4158T| 4367M (2)|999:59:59 | | | Q1,01 | P->S | QC (RAND) |
| 3 | MERGE JOIN CARTESIAN | | 33T| 4158T| 4367M (2)|999:59:59 | | | Q1,01 | PCWP | |
| 4 | SORT JOIN | | | | | | | | Q1,01 | PCWP | |
| 5 | PX RECEIVE | | 8439K| 829M| 3175 (2)| 00:00:39 | | | Q1,01 | PCWP | |
| 6 | PX SEND BROADCAST | :TQ10000 | 8439K| 829M| 3175 (2)| 00:00:39 | | | Q1,00 | P->P | BROADCAST |
| 7 | PX BLOCK ITERATOR | | 8439K| 829M| 3175 (2)| 00:00:39 | 1 | 16 | Q1,00 | PCWC | |
| 8 | TABLE ACCESS FULL| SESSIONS | 8439K| 829M| 3175 (2)| 00:00:39 | 1 | 16 | Q1,00 | PCWP | |
| 9 | BUFFER SORT | | 4013K| 122M| 4367M (2)|999:59:59 | | | Q1,01 | PCWP | |
| 10 | PX BLOCK ITERATOR | | 4013K| 122M| 532 (4)| 00:00:07 | 1 | 16 | Q1,01 | PCWC | |
| 11 | TABLE ACCESS FULL | SOURCE_EVENTS | 4013K| 122M| 532 (4)| 00:00:07 | 1 | 16 | Q1,01 | PCWP | |
---------------------------------------------------------------------------------------------------------------------------------------

1 rows selected


Well done SQL Tuning Advisor, a good answer. It immediately spotted the Cartesian product and it recommends with a rationale that it would be expensive!


II - SQL Access Advisor

SQL Access advisor is another Advisory Framework tool which provides primarily advice on the creation of indexes, materialized views, materialized view logs to improve query performance and response time.

Both SQL Tuning Advisor and SQL Access Advisor tools are quite powerful as they can source the SQL they will tune automatcially from multiple different sources, including SQL cache, AWR, SQL tuning Sets and user defined workloads. Look at the Oracle documentation to find out how all this is possible under OEM Database Control.

What I focus on here is how to quickly pass through these tools ad-hoc SQL that the developer will bring to you and will demand to be tuned there and then.

So using the QUICK_TUNE procedure from the DBMS_ADVISOR package here is how you would tune a nasty single SQL statement for better data access paths with SQL Access Advisor.

1. Create tuning task

In the schema where the table is run the following

VARIABLE tname VARCHAR2(30);
VARIABLE sql_stmt VARCHAR2(30);
EXECUTE :sql_stmt := 'select count(*) from sessions where short_code=''abracadambra'' ';
EXECUTE :tname := 'myquicktunetask';
EXECUTE DBMS_ADVISOR.quick_tune(dbms_advisor.sqlaccess_advisor, :tname, :sql_stmt);


2. Check to see the task is there

Again to see the task myquicktunetask which you just created run in the schema

SQL> select task_name from user_advisor_log
TASK_NAME
------------------------------
TASK_51415
myquicktunetask

2 rows selected


3. See tuning advice

Now, to see the advice you get you will have to look in the DBA dictionary view
DBA_ADVISOR_ACTIONS
. So login as DBA and filter for the task_name='myquicktunetask' in the DBA_ADVISOR_ACTIONS dictionary view. Well, you can view the advice in the USER_ADVISOR_ACTIONS dictionary view as well.

SELECT command,
attr2 ,
attr3 ,
attr4 ,
attr5
FROM dba_advisor_actions
WHERE TASK_NAME='myquicktunetask'

TASK_NAME||'|'||COMMAND||'|'||ATTR2||'|'||ATTR3||'|'||ATTR4||'|'||ATTR5
(CLOB) myquicktunetask|CREATE MATERIALIZED VIEW LOG||ROWID, SEQUENCE| INCLUDING NEW VALUES|("SHORT_CODE")
(CLOB) myquicktunetask|CREATE MATERIALIZED VIEW||REFRESH FAST WITH ROWID|ENABLE QUERY REWRITE|SELECT ACHILLES.SESSIONS.SHORT_CODE C1, COUNT(*) M1 FROM ACHILLES.SESSIONS WHERE (ACHILLES.SESSIONS.SHORT_CODE = 'tl') GROUP BY ACHILLES.SESSIONS.SHORT_CODE
(CLOB) myquicktunetask|GATHER TABLE STATISTICS||-1||


Conclusion

Well I find both tools extremely useful. Both are good starting points in resolving SQL tuning issues and discussions. SQL Tuning Advisor seems to be doing logical optimization mainly by checking your SQL structure and statistics and the SQL Access Advisor does suggest good data access paths, that is mainly work which can be done better on disk.