Merge work:/home/bk/mysql-4.0 into hundin.mysql.fi:/my/bk/mysql-4.0
Docs/manual.texi: Auto merged
This commit is contained in:
commit
8dca301f4b
765
Docs/manual.texi
765
Docs/manual.texi
@ -4113,7 +4113,7 @@ Nothing; We aim towards full ANSI 92 / ANSI 99 compliancy.
|
|||||||
|
|
||||||
|
|
||||||
@node Comparisons, , TODO, Introduction
|
@node Comparisons, , TODO, Introduction
|
||||||
@section How MySQL Compares to Other Open Source Databases
|
@section How MySQL Compares to Other Databases
|
||||||
|
|
||||||
@cindex databases, MySQL vs. others
|
@cindex databases, MySQL vs. others
|
||||||
@cindex comparisons, MySQL vs. others
|
@cindex comparisons, MySQL vs. others
|
||||||
@ -4124,9 +4124,10 @@ tests against @code{Oracle}, @code{DB/2}, @code{Microsoft SQL Server}
|
|||||||
and other commercial products. Due to legal reasons we are restricted
|
and other commercial products. Due to legal reasons we are restricted
|
||||||
from publishing some of those benchmarks in our reference manual.
|
from publishing some of those benchmarks in our reference manual.
|
||||||
|
|
||||||
This section includes a comparison with @code{PostgreSQL} as it is
|
This section includes a comparison with @code{mSQL} for historical
|
||||||
also an Open Source database. If you have benchmark results that we
|
reasons and with @code{PostgreSQL} as it is also an Open Source
|
||||||
can publish, please contact us at @email{benchmarks@@mysql.com}.
|
database. If you have benchmark results that we can publish, please
|
||||||
|
contact us at @email{benchmarks@@mysql.com}.
|
||||||
|
|
||||||
For comparative lists of all supported functions and types as well
|
For comparative lists of all supported functions and types as well
|
||||||
as measured operational limits of many different database systems,
|
as measured operational limits of many different database systems,
|
||||||
@ -4134,12 +4135,513 @@ see the @code{crash-me} web page at
|
|||||||
@uref{http://www.mysql.com/information/crash-me.php}.
|
@uref{http://www.mysql.com/information/crash-me.php}.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Compare PostgreSQL:: How MySQL Compares to PostgreSQL
|
* Compare mSQL:: How MySQL compares to @code{mSQL}
|
||||||
|
* Compare PostgreSQL:: How MySQL Compares to @code{PostgreSQL}
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@node Compare PostgreSQL, , Comparisons, Comparisons
|
@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
|
||||||
@subsection How MySQL Compares to PostgreSQL
|
@subsection How MySQL Compares to @code{mSQL}
|
||||||
|
|
||||||
|
@cindex mSQL, MySQL vs mSQL, overview
|
||||||
|
@table @strong
|
||||||
|
@item Performance
|
||||||
|
|
||||||
|
For a true comparison of speed, consult the growing MySQL benchmark
|
||||||
|
suite. @xref{MySQL Benchmarks}.
|
||||||
|
|
||||||
|
Because there is no thread creation overhead, a small parser, few
|
||||||
|
features, and simple security, @code{mSQL} should be quicker at:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Tests that perform repeated connects and disconnects, running a very
|
||||||
|
simple query during each connection.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{INSERT} operations into very simple tables with few columns and keys.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{CREATE TABLE} and @code{DROP TABLE}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{SELECT} on something that isn't an index. (A table scan is very
|
||||||
|
easy.)
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Because these operations are so simple, it is hard to be better at
|
||||||
|
them when you have a higher startup overhead. After the connection
|
||||||
|
is established, MySQL should perform much better.
|
||||||
|
|
||||||
|
On the other hand, MySQL is much faster than @code{mSQL} (and
|
||||||
|
most other SQL implementations) on the following:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Complex @code{SELECT} operations.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Retrieving large results (MySQL has a better, faster, and safer
|
||||||
|
protocol).
|
||||||
|
|
||||||
|
@item
|
||||||
|
Tables with variable-length strings, because MySQL has more efficient
|
||||||
|
handling and can have indexes on @code{VARCHAR} columns.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Handling tables with many columns.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Handling tables with large record lengths.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{SELECT} with many expressions.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{SELECT} on large tables.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Handling many connections at the same time. MySQL is fully
|
||||||
|
multi-threaded. Each connection has its own thread, which means that
|
||||||
|
no thread has to wait for another (unless a thread is modifying
|
||||||
|
a table another thread wants to access). In @code{mSQL}, once one
|
||||||
|
connection is established, all others must wait until the first has
|
||||||
|
finished, regardless of whether the connection is running a query
|
||||||
|
that is short or long. When the first connection terminates, the
|
||||||
|
next can be served, while all the others wait again, etc.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Joins.
|
||||||
|
@code{mSQL} can become pathologically slow if you change the order of
|
||||||
|
tables in a @code{SELECT}. In the benchmark suite, a time more than
|
||||||
|
15000 times slower than MySQL was seen. This is due to @code{mSQL}'s
|
||||||
|
lack of a join optimiser to order tables in the optimal order.
|
||||||
|
However, if you put the tables in exactly the right order in
|
||||||
|
@code{mSQL}2 and the @code{WHERE} is simple and uses index columns,
|
||||||
|
the join will be relatively fast!
|
||||||
|
@xref{MySQL Benchmarks}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{ORDER BY} and @code{GROUP BY}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{DISTINCT}.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Using @code{TEXT} or @code{BLOB} columns.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@item SQL Features
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item @code{GROUP BY} and @code{HAVING}.
|
||||||
|
@code{mSQL} does not support @code{GROUP BY} at all.
|
||||||
|
MySQL supports a full @code{GROUP BY} with both @code{HAVING} and
|
||||||
|
the following functions: @code{COUNT()}, @code{AVG()}, @code{MIN()},
|
||||||
|
@code{MAX()}, @code{SUM()}, and @code{STD()}. @code{COUNT(*)} is
|
||||||
|
optimised to return very quickly if the @code{SELECT} retrieves from
|
||||||
|
one table, no other columns are retrieved, and there is no
|
||||||
|
@code{WHERE} clause. @code{MIN()} and @code{MAX()} may take string
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
@item @code{INSERT} and @code{UPDATE} with calculations.
|
||||||
|
MySQL can do calculations in an @code{INSERT} or @code{UPDATE}.
|
||||||
|
For example:
|
||||||
|
|
||||||
|
@example
|
||||||
|
mysql> UPDATE SET x=x*10+y WHERE x<20;
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@item Aliasing.
|
||||||
|
MySQL has column aliasing.
|
||||||
|
|
||||||
|
@item Qualifying column names.
|
||||||
|
In MySQL, if a column name is unique among the tables used in a
|
||||||
|
query, you do not have to use the full qualifier.
|
||||||
|
|
||||||
|
@item @code{SELECT} with functions.
|
||||||
|
MySQL has many functions (too many to list here; see @ref{Functions}).
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@item Disk Space Efficiency
|
||||||
|
That is, how small can you make your tables?
|
||||||
|
|
||||||
|
MySQL has very precise types, so you can create tables that take
|
||||||
|
very little space. An example of a useful MySQL datatype is the
|
||||||
|
@code{MEDIUMINT} that is 3 bytes long. If you have 100,000,000
|
||||||
|
records, saving even one byte per record is very important.
|
||||||
|
|
||||||
|
@code{mSQL2} has a more limited set of column types, so it is
|
||||||
|
more difficult to get small tables.
|
||||||
|
|
||||||
|
@item Stability
|
||||||
|
This is harder to judge objectively. For a discussion of MySQL
|
||||||
|
stability, see @ref{Stability}.
|
||||||
|
|
||||||
|
We have no experience with @code{mSQL} stability, so we cannot say
|
||||||
|
anything about that.
|
||||||
|
|
||||||
|
@item Price
|
||||||
|
Another important issue is the license. MySQL has a
|
||||||
|
more flexible license than @code{mSQL}, and is also less expensive
|
||||||
|
than @code{mSQL}. Whichever product you choose to use, remember to
|
||||||
|
at least consider paying for a license or e-mail support.
|
||||||
|
|
||||||
|
@item Perl Interfaces
|
||||||
|
MySQL has basically the same interfaces to Perl as @code{mSQL} with
|
||||||
|
some added features.
|
||||||
|
|
||||||
|
@item JDBC (Java)
|
||||||
|
MySQL currently has a lot of different JDBC drivers:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
The mm driver: A type 4 JDBC driver by Mark Matthews
|
||||||
|
@email{mmatthew@@ecn.purdue.edu}. This is released under the LGPL.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The Resin driver. This is a commercial JDBC driver released under open
|
||||||
|
source. @uref{http://www.caucho.com/projects/jdbc-mysql/index.xtp}
|
||||||
|
|
||||||
|
@item
|
||||||
|
The gwe driver: A Java interface by GWE technologies (not supported anymore).
|
||||||
|
|
||||||
|
@item
|
||||||
|
The jms driver: An improved gwe driver by Xiaokun Kelvin ZHU
|
||||||
|
@email{X.Zhu@@brad.ac.uk} (not supported anymore).
|
||||||
|
|
||||||
|
@item
|
||||||
|
The twz driver: A type 4 JDBC driver by Terrence W. Zellers
|
||||||
|
@email{zellert@@voicenet.com}. This is commercial but is free for private
|
||||||
|
and educational use (not supported anymore).
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The recommended driver is the mm driver. The Resin driver may also be
|
||||||
|
good (at least the benchmarks looks good), but we haven't received that
|
||||||
|
much information about this yet.
|
||||||
|
|
||||||
|
We know that @code{mSQL} has a JDBC driver, but we have too little
|
||||||
|
experience with it to compare.
|
||||||
|
|
||||||
|
@item Rate of Development
|
||||||
|
MySQL has a small core team of developers, but we are quite
|
||||||
|
used to coding C and C++ very rapidly. Because threads, functions,
|
||||||
|
@code{GROUP BY}, and so on are still not implemented in @code{mSQL}, it
|
||||||
|
has a lot of catching up to do. To get some perspective on this, you
|
||||||
|
can view the @code{mSQL} @file{HISTORY} file for the last year and
|
||||||
|
compare it with the News section of the MySQL Reference Manual
|
||||||
|
(@pxref{News}). It should be pretty obvious which one has developed
|
||||||
|
most rapidly.
|
||||||
|
|
||||||
|
@item Utility Programs
|
||||||
|
Both @code{mSQL} and MySQL have many interesting third-party
|
||||||
|
tools. Because it is very easy to port upward (from @code{mSQL} to
|
||||||
|
MySQL), almost all the interesting applications that are available for
|
||||||
|
@code{mSQL} are also available for MySQL.
|
||||||
|
|
||||||
|
MySQL comes with a simple @code{msql2mysql} program that fixes
|
||||||
|
differences in spelling between @code{mSQL} and MySQL for the
|
||||||
|
most-used C API functions.
|
||||||
|
For example, it changes instances of @code{msqlConnect()} to
|
||||||
|
@code{mysql_connect()}. Converting a client program from @code{mSQL} to
|
||||||
|
MySQL usually requires only minor effort.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@menu
|
||||||
|
* Using mSQL tools:: How to convert @code{mSQL} tools for MySQL
|
||||||
|
* Protocol differences:: How @code{mSQL} and MySQL Client/Server Communications Protocols Differ
|
||||||
|
* Syntax differences:: How @code{mSQL} 2.0 SQL Syntax Differs from MySQL
|
||||||
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
|
@node Using mSQL tools, Protocol differences, Compare mSQL, Compare mSQL
|
||||||
|
@subsubsection How to Convert @code{mSQL} Tools for MySQL
|
||||||
|
|
||||||
|
@cindex MySQL tools, conversion
|
||||||
|
@cindex converting, tools
|
||||||
|
@cindex tools, converting
|
||||||
|
|
||||||
|
According to our experience, it doesn't take long to convert tools
|
||||||
|
such as @code{msql-tcl} and @code{msqljava} that use the
|
||||||
|
@code{mSQL} C API so that they work with the MySQL C API.
|
||||||
|
|
||||||
|
The conversion procedure is:
|
||||||
|
|
||||||
|
@enumerate
|
||||||
|
@item
|
||||||
|
Run the shell script @code{msql2mysql} on the source. This requires
|
||||||
|
the @code{replace} program, which is distributed with MySQL.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Compile.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Fix all compiler errors.
|
||||||
|
@end enumerate
|
||||||
|
|
||||||
|
Differences between the @code{mSQL} C API and the MySQL C API are:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
MySQL uses a @code{MYSQL} structure as a connection type (@code{mSQL}
|
||||||
|
uses an @code{int}).
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{mysql_connect()} takes a pointer to a @code{MYSQL} structure as a
|
||||||
|
parameter. It is easy to define one globally or to use @code{malloc()}
|
||||||
|
to get one. @code{mysql_connect()} also takes two parameters for
|
||||||
|
specifying the user and password. You may set these to
|
||||||
|
@code{NULL, NULL} for default use.
|
||||||
|
|
||||||
|
@item
|
||||||
|
@code{mysql_error()} takes the @code{MYSQL} structure as a parameter.
|
||||||
|
Just add the parameter to your old @code{msql_error()} code if you are
|
||||||
|
porting old code.
|
||||||
|
|
||||||
|
@item
|
||||||
|
MySQL returns an error number and a text error message for all
|
||||||
|
errors. @code{mSQL} returns only a text error message.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Some incompatibilities exist as a result of MySQL supporting
|
||||||
|
multiple connections to the server from the same process.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@node Protocol differences, Syntax differences, Using mSQL tools, Compare mSQL
|
||||||
|
@subsubsection How @code{mSQL} and MySQL Client/Server Communications Protocols Differ
|
||||||
|
|
||||||
|
@cindex communications protocols
|
||||||
|
@cindex mSQL vs. MySQL, protocol
|
||||||
|
|
||||||
|
There are enough differences that it is impossible
|
||||||
|
(or at least not easy) to support both.
|
||||||
|
|
||||||
|
The most significant ways in which the MySQL protocol differs
|
||||||
|
from the @code{mSQL} protocol are listed below:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
A message buffer may contain many result rows.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The message buffers are dynamically enlarged if the query or the
|
||||||
|
result is bigger than the current buffer, up to a configurable server
|
||||||
|
and client limit.
|
||||||
|
|
||||||
|
@item
|
||||||
|
All packets are numbered to catch duplicated or missing packets.
|
||||||
|
|
||||||
|
@item
|
||||||
|
All column values are sent in ASCII. The lengths of columns and rows
|
||||||
|
are sent in packed binary coding (1, 2, or 3 bytes).
|
||||||
|
|
||||||
|
@item
|
||||||
|
MySQL can read in the result unbuffered (without having to store the
|
||||||
|
full set in the client).
|
||||||
|
|
||||||
|
@item
|
||||||
|
If a single read/write takes more than 30 seconds, the server closes
|
||||||
|
the connection.
|
||||||
|
|
||||||
|
@item
|
||||||
|
If a connection is idle for 8 hours, the server closes the connection.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
|
@node Syntax differences, , Protocol differences, Compare mSQL
|
||||||
|
@subsubsection How @code{mSQL} 2.0 SQL Syntax Differs from MySQL
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{Column types}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Has the following additional types (among others;
|
||||||
|
@pxref{CREATE TABLE, , @code{CREATE TABLE}}):
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@c FIX bad lingo, needs rephrasing
|
||||||
|
@code{ENUM} type for one of a set of strings.
|
||||||
|
@item
|
||||||
|
@c FIX bad lingo, needs rephrasing
|
||||||
|
@code{SET} type for many of a set of strings.
|
||||||
|
@item
|
||||||
|
@code{BIGINT} type for 64-bit integers.
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
MySQL also supports
|
||||||
|
the following additional type attributes:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@code{UNSIGNED} option for integer columns.
|
||||||
|
@item
|
||||||
|
@code{ZEROFILL} option for integer columns.
|
||||||
|
@item
|
||||||
|
@code{AUTO_INCREMENT} option for integer columns that are a
|
||||||
|
@code{PRIMARY KEY}.
|
||||||
|
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
|
||||||
|
@item
|
||||||
|
@code{DEFAULT} value for all columns.
|
||||||
|
@end itemize
|
||||||
|
@item mSQL2
|
||||||
|
@code{mSQL} column types correspond to the MySQL types shown below:
|
||||||
|
@multitable @columnfractions .15 .85
|
||||||
|
@item @code{mSQL} @strong{type} @tab @strong{Corresponding MySQL type}
|
||||||
|
@item @code{CHAR(len)} @tab @code{CHAR(len)}
|
||||||
|
@item @code{TEXT(len)} @tab @code{TEXT(len)}. @code{len} is the maximal length.
|
||||||
|
And @code{LIKE} works.
|
||||||
|
@item @code{INT} @tab @code{INT}. With many more options!
|
||||||
|
@item @code{REAL} @tab @code{REAL}. Or @code{FLOAT}. Both 4- and 8-byte versions are available.
|
||||||
|
@item @code{UINT} @tab @code{INT UNSIGNED}
|
||||||
|
@item @code{DATE} @tab @code{DATE}. Uses ANSI SQL format rather than @code{mSQL}'s own format.
|
||||||
|
@item @code{TIME} @tab @code{TIME}
|
||||||
|
@item @code{MONEY} @tab @code{DECIMAL(12,2)}. A fixed-point value with two decimals.
|
||||||
|
@end multitable
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{Index Creation}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Indexes may be specified at table creation time with the @code{CREATE TABLE}
|
||||||
|
statement.
|
||||||
|
@item mSQL
|
||||||
|
Indexes must be created after the table has been created, with separate
|
||||||
|
@code{CREATE INDEX} statements.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{To Insert a Unique Identifier into a Table}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Use @code{AUTO_INCREMENT} as a column type
|
||||||
|
specifier.
|
||||||
|
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
|
||||||
|
@item mSQL
|
||||||
|
Create a @code{SEQUENCE} on a table and select the @code{_seq} column.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{To Obtain a Unique Identifier for a Row}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Add a @code{PRIMARY KEY} or @code{UNIQUE} key to the table and use this.
|
||||||
|
New in Version 3.23.11: If the @code{PRIMARY} or @code{UNIQUE} key consists of only one
|
||||||
|
column and this is of type integer, one can also refer to it as
|
||||||
|
@code{_rowid}.
|
||||||
|
@item mSQL
|
||||||
|
Use the @code{_rowid} column. Observe that @code{_rowid} may change over time
|
||||||
|
depending on many factors.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{To Get the Time a Column Was Last Modified}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Add a @code{TIMESTAMP} column to the table. This column is automatically set
|
||||||
|
to the current date and time for @code{INSERT} or @code{UPDATE} statements if
|
||||||
|
you don't give the column a value or if you give it a @code{NULL} value.
|
||||||
|
|
||||||
|
@item mSQL
|
||||||
|
Use the @code{_timestamp} column.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{@code{NULL} Value Comparisons}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
MySQL follows
|
||||||
|
ANSI SQL, and a comparison with @code{NULL} is always @code{NULL}.
|
||||||
|
@item mSQL
|
||||||
|
In @code{mSQL}, @code{NULL = NULL} is TRUE. You
|
||||||
|
must change @code{=NULL} to @code{IS NULL} and @code{<>NULL} to
|
||||||
|
@code{IS NOT NULL} when porting old code from @code{mSQL} to MySQL.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{String Comparisons}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Normally, string comparisons are performed in case-independent fashion with
|
||||||
|
the sort order determined by the current character set (ISO-8859-1 Latin1 by
|
||||||
|
default). If you don't like this, declare your columns with the
|
||||||
|
@code{BINARY} attribute, which causes comparisons to be done according to the
|
||||||
|
ASCII order used on the MySQL server host.
|
||||||
|
@item mSQL
|
||||||
|
All string comparisons are performed in case-sensitive fashion with
|
||||||
|
sorting in ASCII order.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{Case-insensitive Searching}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
@code{LIKE} is a case-insensitive or case-sensitive operator, depending on
|
||||||
|
the columns involved. If possible, MySQL uses indexes if the
|
||||||
|
@code{LIKE} argument doesn't start with a wild-card character.
|
||||||
|
@item mSQL
|
||||||
|
Use @code{CLIKE}.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{Handling of Trailing Spaces}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Strips all spaces at the end of @code{CHAR} and @code{VARCHAR}
|
||||||
|
columns. Use a @code{TEXT} column if this behavior is not desired.
|
||||||
|
@item mSQL
|
||||||
|
Retains trailing space.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{@code{WHERE} Clauses}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
MySQL correctly prioritises everything (@code{AND} is evaluated
|
||||||
|
before @code{OR}). To get @code{mSQL} behavior in MySQL, use
|
||||||
|
parentheses (as shown in an example below).
|
||||||
|
@item mSQL
|
||||||
|
Evaluates everything from left to right. This means that some logical
|
||||||
|
calculations with more than three arguments cannot be expressed in any
|
||||||
|
way. It also means you must change some queries when you upgrade to
|
||||||
|
MySQL. You do this easily by adding parentheses. Suppose you
|
||||||
|
have the following @code{mSQL} query:
|
||||||
|
@example
|
||||||
|
mysql> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;
|
||||||
|
@end example
|
||||||
|
To make MySQL evaluate this the way that @code{mSQL} would,
|
||||||
|
you must add parentheses:
|
||||||
|
@example
|
||||||
|
mysql> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
|
||||||
|
@end example
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@noindent
|
||||||
|
@strong{Access Control}
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item MySQL
|
||||||
|
Has tables to store grant (permission) options per user, host, and
|
||||||
|
database. @xref{Privileges}.
|
||||||
|
@item mSQL
|
||||||
|
Has a file @file{mSQL.acl} in which you can grant read/write privileges for
|
||||||
|
users.
|
||||||
|
@end table
|
||||||
|
|
||||||
|
|
||||||
|
@node Compare PostgreSQL, , Compare mSQL, Comparisons
|
||||||
|
@subsection How MySQL Compares to @code{PostgreSQL}
|
||||||
|
|
||||||
@cindex PostgreSQL vs. MySQL, overview
|
@cindex PostgreSQL vs. MySQL, overview
|
||||||
|
|
||||||
@ -4166,6 +4668,7 @@ can offer, you should use @code{PostgreSQL}.
|
|||||||
@menu
|
@menu
|
||||||
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
|
* MySQL-PostgreSQL goals:: MySQL and PostgreSQL development strategies
|
||||||
* MySQL-PostgreSQL features:: Featurewise Comparison of MySQL and PostgreSQL
|
* MySQL-PostgreSQL features:: Featurewise Comparison of MySQL and PostgreSQL
|
||||||
|
* MySQL-PostgreSQL benchmarks:: Benchmarking MySQL and PostgreSQL
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@ -4211,7 +4714,7 @@ in our opinion, fewer bugs. Because we are the authors of the MySQL server
|
|||||||
code, we are better able to coordinate new features and releases.
|
code, we are better able to coordinate new features and releases.
|
||||||
|
|
||||||
|
|
||||||
@node MySQL-PostgreSQL features, , MySQL-PostgreSQL goals, Compare PostgreSQL
|
@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
|
||||||
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
|
@subsubsection Featurewise Comparison of MySQL and PostgreSQL
|
||||||
|
|
||||||
@cindex PostgreSQL vs. MySQL, features
|
@cindex PostgreSQL vs. MySQL, features
|
||||||
@ -4470,6 +4973,252 @@ For a complete list of drawbacks, you should also examine the first table
|
|||||||
in this section.
|
in this section.
|
||||||
|
|
||||||
|
|
||||||
|
@node MySQL-PostgreSQL benchmarks, , MySQL-PostgreSQL features, Compare PostgreSQL
|
||||||
|
@subsubsection Benchmarking MySQL and PostgreSQL
|
||||||
|
|
||||||
|
@cindex PostgreSQL vs. MySQL, benchmarks
|
||||||
|
|
||||||
|
The only open source benchmark that we know of that can be used to
|
||||||
|
benchmark MySQL and PostgreSQL (and other databases) is our own. It can
|
||||||
|
be found at @uref{http://www.mysql.com/information/benchmarks.html}.
|
||||||
|
|
||||||
|
We have many times asked the PostgreSQL developers and some PostgreSQL
|
||||||
|
users to help us extend this benchmark to make it the definitive benchmark
|
||||||
|
for databases, but unfortunately we haven't gotten any feedback for this.
|
||||||
|
|
||||||
|
We the MySQL developers have, because of this, spent a lot of hours to get
|
||||||
|
maximum performance from PostgreSQL for the benchmarks, but because we
|
||||||
|
don't know PostgreSQL intimately, we are sure that there are things that
|
||||||
|
we have missed. We have on the benchmark page documented exactly how we
|
||||||
|
did run the benchmark so that it should be easy for anyone to repeat and
|
||||||
|
verify our results.
|
||||||
|
|
||||||
|
The benchmarks are usually run with and without the @code{--fast} option.
|
||||||
|
When run with @code{--fast} we are trying to use every trick the server can
|
||||||
|
do to get the code to execute as fast as possible. The idea is that the
|
||||||
|
normal run should show how the server would work in a default setup and
|
||||||
|
the @code{--fast} run shows how the server would do if the application
|
||||||
|
developer would use extensions in the server to make his application run
|
||||||
|
faster.
|
||||||
|
|
||||||
|
When running with PostgreSQL and @code{--fast} we do a @code{VACUUM()}
|
||||||
|
after every major table @code{UPDATE} and @code{DROP TABLE} to make the
|
||||||
|
database in perfect shape for the following @code{SELECT}s. The time for
|
||||||
|
@code{VACUUM()} is measured separately.
|
||||||
|
|
||||||
|
When running with PostgreSQL 7.1.1 we could, however, not run with
|
||||||
|
@code{--fast} because during the @code{INSERT} test, the postmaster (the
|
||||||
|
PostgreSQL deamon) died and the database was so corrupted that it was
|
||||||
|
impossible to restart postmaster. After this happened twice, we decided
|
||||||
|
to postpone the @code{--fast} test until next PostgreSQL release. The
|
||||||
|
details about the machine we run the benchmark can be found on the
|
||||||
|
benchmark page.
|
||||||
|
|
||||||
|
Before going to the other benchmarks we know of, we would like to give
|
||||||
|
some background on benchmarks:
|
||||||
|
|
||||||
|
It's very easy to write a test that shows @strong{any} database to be the best
|
||||||
|
database in the world, by just restricting the test to something the
|
||||||
|
database is very good at and not testing anything that the database is
|
||||||
|
not good at. If one, after doing this, summarises the result with as
|
||||||
|
a single figure, things are even easier.
|
||||||
|
|
||||||
|
This would be like us measuring the speed of MySQL compared to PostgreSQL
|
||||||
|
by looking at the summary time of the MySQL benchmarks on our web page.
|
||||||
|
Based on this MySQL would be more than 40 times faster than PostgreSQL,
|
||||||
|
something that is of course not true. We could make things even worse
|
||||||
|
by just taking the test where PostgreSQL performs worst and claim that
|
||||||
|
MySQL is more than 2000 times faster than PostgreSQL.
|
||||||
|
|
||||||
|
The case is that MySQL does a lot of optimisations that PostgreSQL
|
||||||
|
doesn't do. This is of course also true the other way around. An SQL
|
||||||
|
optimiser is a very complex thing, and a company could spend years on
|
||||||
|
just making the optimiser faster and faster.
|
||||||
|
|
||||||
|
When looking at the benchmark results you should look for things that
|
||||||
|
you do in your application and just use these results to decide which
|
||||||
|
database would be best suited for your application. The benchmark
|
||||||
|
results also shows things a particular database is not good at and should
|
||||||
|
give you a notion about things to avoid and what you may have to do in
|
||||||
|
other ways.
|
||||||
|
|
||||||
|
We know of two benchmark tests that claims that PostgreSQL performs better
|
||||||
|
than MySQL. These both where multi-user tests, a test that we here at
|
||||||
|
MySQL AB haven't had time to write and include in the benchmark suite,
|
||||||
|
mainly because it's a big task to do this in a manner that is fair against
|
||||||
|
all databases.
|
||||||
|
|
||||||
|
One is the benchmark paid for by Great Bridge, the company that for 16 months
|
||||||
|
attempted to build a business based on PostgreSQL but now has ceased
|
||||||
|
operations. This is the probably worst benchmark we have ever seen anyone
|
||||||
|
conduct. This was not only tuned to only test what PostgreSQL is absolutely
|
||||||
|
best at, it was also totally unfair against every other database involved in
|
||||||
|
the test.
|
||||||
|
|
||||||
|
@strong{Note}: We know that even some of the main PostgreSQL
|
||||||
|
developers did not like the way Great Bridge conducted the benchmark, so we
|
||||||
|
don't blame the PostgreSQL team for the way the benchmark was done.
|
||||||
|
|
||||||
|
This benchmark has been condemned in a lot of postings and newsgroups so
|
||||||
|
we will here just shortly repeat some things that were wrong with it.
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
The tests were run with an expensive commercial tool, that makes it
|
||||||
|
impossible for an open source company like us to verify the benchmarks,
|
||||||
|
or even check how the benchmarks were really done. The tool is not even
|
||||||
|
a true benchmark tool, but an application/setup testing tool. To refer
|
||||||
|
this as a ``standard'' benchmark tool is to stretch the truth a long way.
|
||||||
|
|
||||||
|
@item
|
||||||
|
Great Bridge admitted that they had optimised the PostgreSQL database
|
||||||
|
(with @code{VACUUM()} before the test) and tuned the startup for the tests,
|
||||||
|
something they hadn't done for any of the other databases involved. To
|
||||||
|
say ``This process optimises indexes and frees up disk space a bit. The
|
||||||
|
optimised indexes boost performance by some margin.'' Our benchmarks
|
||||||
|
clearly indicate that the difference in running a lot of selects on a
|
||||||
|
database with and without @code{VACUUM()} can easily differ by a factor
|
||||||
|
of ten.
|
||||||
|
|
||||||
|
@item
|
||||||
|
The test results were also strange. The AS3AP test documentation
|
||||||
|
mentions that the test does ``selections, simple joins, projections,
|
||||||
|
aggregates, one-tuple updates, and bulk updates''.
|
||||||
|
|
||||||
|
PostgreSQL is good at doing @code{SELECT}s and @code{JOIN}s (especially
|
||||||
|
after a @code{VACUUM()}), but doesn't perform as well on @code{INSERT}s or
|
||||||
|
@code{UPDATE}s. The benchmarks seem to indicate that only @code{SELECT}s
|
||||||
|
were done (or very few updates). This could easily explain they good results
|
||||||
|
for PostgreSQL in this test. The bad results for MySQL will be obvious a
|
||||||
|
bit down in this document.
|
||||||
|
|
||||||
|
@item
|
||||||
|
They did run the so-called benchmark from a Windows machine against a
|
||||||
|
Linux machine over ODBC, a setup that no normal database user would ever
|
||||||
|
do when running a heavy multi-user application. This tested more the
|
||||||
|
ODBC driver and the Windows protocol used between the clients than the
|
||||||
|
database itself.
|
||||||
|
|
||||||
|
@item
|
||||||
|
When running the database against Oracle and MS-SQL (Great Bridge has
|
||||||
|
indirectly indicated that the databases they used in the test), they
|
||||||
|
didn't use the native protocol but instead ODBC. Anyone that has ever
|
||||||
|
used Oracle knows that all real application uses the native interface
|
||||||
|
instead of ODBC. Doing a test through ODBC and claiming that the results
|
||||||
|
had anything to do with using the database in a real-world situation can't
|
||||||
|
be regarded as fair. They should have done two tests with and without ODBC
|
||||||
|
to provide the right facts (after having got experts to tune all involved
|
||||||
|
databases of course).
|
||||||
|
|
||||||
|
@item
|
||||||
|
They refer to the TPC-C tests, but they don't mention anywhere that the
|
||||||
|
test they did was not a true TPC-C test and they were not even allowed to
|
||||||
|
call it a TPC-C test. A TPC-C test can only be conducted by the rules
|
||||||
|
approved by the TPC Council (@uref{http://www.tpc.org/}). Great Bridge
|
||||||
|
didn't do that. By doing this they have both violated the TPC trademark
|
||||||
|
and miscredited their own benchmarks. The rules set by the TPC Council
|
||||||
|
are very strict to ensure that no one can produce false results or make
|
||||||
|
unprovable statements. Apparently Great Bridge wasn't interested in
|
||||||
|
doing this.
|
||||||
|
|
||||||
|
@item
|
||||||
|
After the first test, we contacted Great Bridge and mentioned to them
|
||||||
|
some of the obvious mistakes they had done with MySQL:
|
||||||
|
|
||||||
|
@itemize @minus
|
||||||
|
@item
|
||||||
|
Running with a debug version of our ODBC driver
|
||||||
|
|
||||||
|
@item
|
||||||
|
Running on a Linux system that wasn't optimised for threads
|
||||||
|
|
||||||
|
@item
|
||||||
|
Using an old MySQL version when there was a recommended newer one available
|
||||||
|
|
||||||
|
@item
|
||||||
|
Not starting MySQL with the right options for heavy multi-user use (the
|
||||||
|
default installation of MySQL is tuned for minimal resource use).
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Great Bridge did run a new test, with our optimised ODBC driver and with
|
||||||
|
better startup options for MySQL, but refused to either use our updated
|
||||||
|
glibc library or our standard binary (used by 80% of our users), which was
|
||||||
|
statically linked with a fixed glibc library.
|
||||||
|
|
||||||
|
According to what we know, Great Bridge did nothing to ensure that the
|
||||||
|
other databases were set up correctly to run well in their test
|
||||||
|
environment. We are sure however that they didn't contact Oracle or
|
||||||
|
Microsoft to ask for their advice in this matter ;)
|
||||||
|
|
||||||
|
@item
|
||||||
|
The benchmark was paid for by Great Bridge, and they decided to publish
|
||||||
|
only partial, chosen results (instead of publishing it all).
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Tim Perdue, a long time PostgreSQL fan and a reluctant MySQL user
|
||||||
|
published a comparison on PHPbuilder
|
||||||
|
(@uref{http://www.phpbuilder.com/columns/tim20001112.php3}).
|
||||||
|
|
||||||
|
When we became aware of the comparison, we phoned Tim Perdue about this
|
||||||
|
because there were a lot of strange things in his results. For example,
|
||||||
|
he claimed that MySQL had a problem with five users in his tests, when we
|
||||||
|
know that there are users with similar machines as his that are using
|
||||||
|
MySQL with 2000 simultaneous connections doing 400 queries per second.
|
||||||
|
(In this case the limit was the web bandwidth, not the database.)
|
||||||
|
|
||||||
|
It sounded like he was using a Linux kernel that either had some
|
||||||
|
problems with many threads, such as kernels before 2.4, which had a problem
|
||||||
|
with many threads on multi-CPU machines. We have documented in this manual
|
||||||
|
how to fix this and Tim should be aware of this problem.
|
||||||
|
|
||||||
|
The other possible problem could have been an old glibc library and
|
||||||
|
that Tim didn't use a MySQL binary from our site, which is linked with
|
||||||
|
a corrected glibc library, but had compiled a version of his own with.
|
||||||
|
In any of the above cases, the symptom would have been exactly what Tim
|
||||||
|
had measured.
|
||||||
|
|
||||||
|
We asked Tim if we could get access to his data so that we could repeat
|
||||||
|
the benchmark and if he could check the MySQL version on the machine to
|
||||||
|
find out what was wrong and he promised to come back to us about this.
|
||||||
|
He has not done that yet.
|
||||||
|
|
||||||
|
Because of this we can't put any trust in this benchmark either :(
|
||||||
|
|
||||||
|
Over time things also changes and the above benchmarks are not that
|
||||||
|
relevant anymore. MySQL now have a couple of different table handlers
|
||||||
|
with different speed/concurrency tradeoffs. @xref{Table types}. It
|
||||||
|
would be interesting to see how the above tests would run with the
|
||||||
|
different transactional table types in MySQL. PostgreSQL has of course
|
||||||
|
also got new features since the test was made. As the above test are
|
||||||
|
not publicly available there is no way for us to know how the
|
||||||
|
database would preform in the same tests today.
|
||||||
|
|
||||||
|
|
||||||
|
Conclusion:
|
||||||
|
|
||||||
|
The only benchmarks that exist today that anyone can download and run
|
||||||
|
against MySQL and PostgreSQL is the MySQL benchmarks. We here at MySQL
|
||||||
|
believe that open source databases should be tested with open source tools!
|
||||||
|
This is the only way to ensure that no one does tests that nobody can
|
||||||
|
reproduce and use this to claim that a database is better than another.
|
||||||
|
Without knowing all the facts it's impossible to answer the claims of the
|
||||||
|
tester.
|
||||||
|
|
||||||
|
The thing we find strange is that every test we have seen about
|
||||||
|
PostgreSQL, that is impossible to reproduce, claims that PostgreSQL is
|
||||||
|
better in most cases while our tests, which anyone can reproduce,
|
||||||
|
clearly shows otherwise. With this we don't want to say that PostgreSQL
|
||||||
|
isn't good at many things (it is!) or that it isn't faster than MySQL
|
||||||
|
under certain conditions. We would just like to see a fair test where
|
||||||
|
they are very good so that we could get some friendly competition going!
|
||||||
|
|
||||||
|
For more information about our benchmarks suite @xref{MySQL Benchmarks}.
|
||||||
|
|
||||||
|
We are working on an even better benchmark suite, including multi user
|
||||||
|
tests, and a better documentation of what the individual tests really
|
||||||
|
do and how to add more tests to the suite.
|
||||||
|
|
||||||
|
|
||||||
@node Installing, Tutorial, Introduction, Top
|
@node Installing, Tutorial, Introduction, Top
|
||||||
@chapter MySQL Installation
|
@chapter MySQL Installation
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user