Advantages of stored procedures, triggers, indexes

A stored procedure is a set of SQL commands that can be compiled and stored in the server. Once this has been done, clients don’t need to keep re-issuing the entire query but can refer to the stored procedure. This provides better overall performance because the query has to be parsed only once, and less information needs to be sent between the server and the client. You can also raise the conceptual level by having libraries of functions in the server. However, stored procedures of course do increase the load on the database server system, as more of the work is done on the server side and less on the client (application) side. Triggers will also be implemented.

A trigger is effectively a type of stored procedure, one that is invoked when a particular event occurs. For example, you can install a stored procedure that is triggered each time a record is deleted from a transaction table and that stored procedure automatically deletes the corresponding customer from a customer table when all his transactions are deleted.

Indexes are used to find rows with specific column values quickly. Without an index, MySQL must begin with the first row and then read through the entire table to find the relevant rows. The larger the table, the more this costs. If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading sequentially. If you need to access most of the rows, it is faster to read sequentially, because this minimizes disk seeks.

Optimising MYSQL

Hello,

I’d like to share with the Web Collections my knowledge about tuning / tweaking mysql.

First of all, sorry if my English is not perfect. Maybe some sentences may be difficult to understand. So do not hesitate to ask me for explanations :-p

Secondly,
DO NOT CHANGE your setting without understanding what you do.
Make a backup of your my.cnf before editing the /etc/my.cnf
DO THESE CHANGES AT YOUR OWN RISKS.

My article is only to help you to more well understand how tuning mysql.

Optimising mysql is very well commented on the net, and you’ll find huge information on how to do this. There is never “best parameters”, the best parameters is those fits your needs, box hardware, mysql usage…
So, I’ll not give the best parameters but rather how to define these ones. Make some tests, and you’ll quickly find your own parameters.

I’ll give you at the end of this post some web pointers which may help you.

There a lot of available parameters but only few one are very important to tweak your mysql box.

The most important variables are (for me, and it is not exhaustive)

- max_connections
- wait_timeout
- thread_cache_size
- table_cache
- key_buffer_size
- query_cache_size
- tmp_table_size

First of all, how to find your variable, and the mysql usage ?

*VARIABLES

from mysql :
show variables;

or from command line :
mysqladmin variables

*PROCESS / STATUS

from Mysql :
show status;

or from command line
mysqladmin –i10 processlist extended-status

*SOME USEFUL COMMAND FOR YOU BOX USAGE

>Top

>ps –axfu

>vmstat 1

* OPTIMISING MYSQL

To obtain the stat of your mysql server since it has been loaded, run mysqladmin processlist extended-status as mentionned above.

1 – The two most important variables : Table_cache and Key_buffer_size

* If Opened_tables is big, then your table_cache variable is probably too small.
table_cache 64
Open_tables 64
Opened_tables 544468

This is the first serious problem. “The table_cache is the number of open tables for all threads. MySQL, being multi-threaded, may be running many queries on the table at one time, and each of these will open a table.” Therefore, even though we only have a few tables, we will need many more open_tables.

The Opened_tables value is high and shows the number of cache misses. Getting the table_cache size correct is one of the two best things you can do to improve performance.

* If Key_reads is big, then your key_buffer_size variable is probably too small. The cache hit rate can be calculated with Key_reads/Key_read_requests.
key_buffer_size 16M
Key_read_requests 2973620399
Key_reads 8490571
(cache hit rate = 0.0028)

“The key_buffer_size affects the size of the index buffers and the speed of index handling, particularly reading.” The MySQL manual (and other sources) say that “Key_reads/Key_read_request ratio should normally be < 0.01.” This is the other most important thing to get correct. Here the value seems to be correct (< 0.01)

Also check key_write_requests and key_writes.  The key_writes/key_writes_request should normally be < 1 (near 0.5 seems to be fine)

Here is a very interesting web pointer : http://www.databasejournal.com/featu…0897_1402311_3

2 – Others important settings are : Wait_timeout, max_connexion, thread_cache

A little explanation :
Generaly you have a lot of mysql process that are sleeping because wait_timeout are not set low. So I make sure that the wait_timeout is set to a very low value: 15 seconds (for me) . That means MySQL would close any connection that was idle for more than 15 seconds.

The problem is you also have to increment your max_connexion (mine is set to 300) to be sure there is not a lot of idle clients holding connections and blocking out new clients from connecting and getting real work done. The pbm is that the box has to create new threads (MySQL is a multi-threaded server) at a very high rate. That may sucks up a measurable amount of CPU time.

So the solution is to use the Thread_cache (from mysql doc) :
“How many threads we should keep in a cache for reuse. When a client disconnects, the client’s threads are put in the cache if there aren’t more than thread_cache_size threads from before. All new threads are first taken from the cache, and only when the cache is empty is a new thread created. This variable can be increased to improve performance if you have a lot of new connections. (Normally this doesn’t give a notable performance improvement if you have a good thread implementation.) By examing the difference between the Connections and Threads_created you can see how efficient the current thread cache is for you.”

* If Threads_created is big, you may want to increase the thread_cache_size variable. The cache hit rate can be calculated with Threads_created/Connections.
thread_cache_size 0
Threads_created 150022
Connections 150023

This is the second problem that should be fixed. A cache size of zero is the default for my-medium.cnf but the recommended size in my-large.cnf is 8.

you may try this formula : table_cache = opened table / max_used_connection

3 – Finally, you may also have a look at : tmp_table_size and Handler_read_rnd / Handler_read_rnd_next

* If Created_tmp_disk_tables is big, you may want to increase the tmp_table_size variable to get the temporary tables memory-based instead
of disk based.

tmp_table_size 32M
Created_tmp_disk_tables 3227
Created_tmp_tables 159832
Created_tmp_files 4444

Created_tmp_disk_tables are the “number of implicit temporary tables on disk created while executing statements” and Created_tmp_tables are
memory-based. Obviously it is bad if you have to go to disk instead of memory. About 2% of temp tables go to disk, which doesn’t seem too bad
but increasing the tmp_table_size probably couldn’t hurt either.

* If Handler_read_rnd is big, then you probably have a lot of queries that require MySQL to scan whole tables or you have joins that don’t use
keys properly.

Handler_read_rnd 27712353
Handler_read_rnd_next 283536234

These values are high, that we could probably stand to improve the indexes and queries.

I hope this will help some of you to more understand how it is possible to optimise MYSQL to fit your needs, hardaware box, or mysql current usage.

Maybe there is others tweaks to perform, but I know well only these ones. I did setup using these ones on differents mysql box, and generally it did help us to increase performance without have to change hardware (our boxes have 2GB ram)

I forgot to tell you two or three importants things like :

Used MySQL memory = key_buffer + max_connections * (join_buffer + record_buffer + sort_buffer + thread_stack + tmp_table_size)

Notice the max_connexion and the multiplier. connexion increase = memory usage increase too.

Notice key_buffer for a given memory : more you add mem to key buffer, less connexion is less is key buffer, more connexion is

If you change one of these settings for a high value, you system may swap. If you system swap, try lot decrease these values

Also, about table_cache :
Increasing the size of the table cache may really help you. But you must be careful not to make the value too large. All operating systems have a limit on the number “open file pointer” (sorry in french it is called pointer, maybe descriptors is the good translation) a single process may have.
If MySQL tries to open a lot of files, the OS may refuse it and MySQL will generate error message in the error log.

Author: Pascal

Top 10 Qualities of The Perfect Programmer

1. Intellect – can understand the problem, translate and express ideas in clear and readable code, has analytical and logical mind.

2. Personality – has right mixture of personal traits like detail-oriented, creative, flexible, disciplined, sociable, independent etc.

3. Expertise – knowledge and experience for solving client’s problems in the specific context with chosen technologies.

4. Motivation – cares about work, shows enthusiasm, interest and love for programming.

5. Maturity – knows and uses sound software development principles, practices and approaches as agile, design and architecture patterns, domain-driven design, unit testing, refactoring.

6. Pragmatism – understands what is possible, loves simplicity and avoids over-engineering; understands business goals, keeps touch with reality and focus on what should be done.

7. Cooperation – listens, accepts that other people could have better ideas, supports team goals without hidden agenda, shares ideas and knowledge and coach others.

8. Communication – effectively communicates and exchanges ideas, supports knowledge and decisions about the system with clear explanations, justifications and answers.

9. Potential – has professional goals, good learning skills, curiosity, adaptability and performs constant self correction.

10. Vision sees the big picture, understands context, trends and people, aligns actions with team and company implicit goals, contributes into building shared vision for the software system.

Tips For Writing Good Stored Procedures

1. Fully Qualified Names – Always use the fully qualified name when calling stored procedures. This would be the format database_name.schema_name.table_name.

For example, use EXEC master.dbo.Your_Proc_name instead of EXEC Your_Proc_name This is a very common mistake, which causes an extra trip to the procedure cache to get the execution plan for execution. Also try to use the schema name while creating a procedure. Like: CREATE PROCEDURE dbo.Your_Proc_name instead of CREATE PROCEDURE Your_Proc_name

2. The sp_ prefix - Don’t use the “sp_” prefix in a stored procedure name as the “sp_” prefix is reserved for system stored procedures. Any stored procedure that has the “sp_” prefix will cause an extra lookup in the MASTER database If a stored procedure uses same name in both the user database and a system database, the stored procedure in the user database will never get executed.

3. Keywords – Use SQL keywords in capital letters to increase readability. Also use proper indentation to increase readability.

4. SET NOCOUNT ON – This returns the message that shows number of rows affected by SQL statement. This can cause extra network traffic and can have some serious impact on performance when the procedure is called frequently.

5. sp_executeSQL and the KEEPFIXED PLAN options - Both sp_executesql and the KEEPFIXED PLAN option avoid the recompilation of a stored procedure. If you want to provide parameterized dynamic SQL, then go for sp_executesql instead of EXEC(proc_name). Here the execution plan for the procedure is stored with the variable name in cache memory. When the variable values are supplied, then the values are simply mapped to the query, hence no need for a recompilation.

6. SELECT vs SET – A single SELECT statement can assign values to different variables and is much faster than multiple SET statements assigning values to multiple different variables.

Example:
SELECT @Var1 = @Var1 + 1, @Var2 = @Var2 – 1
instead of

SET @Var1 = @Var1 + 1

SET @Var2 = @Var2 – 1

7.WHERE clauses – In a WHERE clause, the various operators used directly affect how fast a query can run. Here are the conditional operators used in the WHERE clause, ordered by their performance.

=, >, <, >=, <=, <>, !=, !>, !<

8.CAST and CONVERT – Try to use CAST instead of CONVERT. CAST is ANSI-92 standard but CONVERT works in MS SQL server only. Also, Convert may be deprecated in future MS SQL releases. It is better to use CONVERT only when you need to format the DATETIME datatype with the style option. CAST cannot do this.

9.Avoid DISTINCT and ORDER BY – If you don’t need the DISTINCT/ORDER BY clause, then try to avoid so. Unnecessary DISTINCT or ORDER BY clauses cause extra work for the database engine. Hence making performance slower.

10.Avoid using cursors – Try to use temporary table/table variables with identity column and then iterate all the tables using WHILE loop and a looping counter, which will map with the identity column.

11.SELECT statements - Try to use only the required number of columns in the SELECT clause instead of using *. Using * returns all columns, which unnecessarily create a fat recordset.

12.Try to use table variables instead of Temporary Tables – Temp tables can cause stored procedures to recompile. But table variables were designed specifically to guard against stored procedure recompiles during execution.

13.Try to use table variables instead of Temporary Tables – Temp tables can cause stored procedures to recompile. But table variables were designed specifically to guard against stored procedure recompiles during execution.

If the result set is not containing a huge number of records then you should stick to table variable, otherwise temp table has its advantages. There is a misconception that temp tables always use the tembdb database but table variable do not. Table variables also use tempdb after a certain size.

14.Subquery vs JOINs -In fact most sub queries can be expressed as an equivalent form of JOIN. subquery is faster when we have to retrieve data from large number of tables because it becomes tedious to join more tables. JOIN is faster to retrieve data from database when we have less number of tables. But try to avoid correlated sub queries because it makes the query much slower.

15.Use proper indexes – You can use the help of the data tuning advisor, but it does not gives the proper result all the time. Index scans are much faster than table scans. So identify the table scans from the execution plans. But when a table returns smaller rows, then it is better to use a table scan.

Getting first and last records using mysql

CREATE TABLE `friends` ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) default NULL, PRIMARY KEY (`id`) )

select * from friends;

==============================
id name
==============================
1 Aditi Shastry
2 Umesh Shastry
3 Girish Bahri
4 Narendra Jattu
5 Abhishek Kumar Singh
6 Sagar Gunupati
==============================

SELECT A.* FROM (SELECT * FROM friends ORDER BY id ASC limit 1) A
UNION
SELECT B.* FROM (SELECT * FROM friends ORDER BY id DESC limit 1) B;

After running this query, you will get the following output,

==============================
id name
==============================
1 Aditi Shastry
6 Sagar Gunupati

Author: Umesh Shastry

« Older entries