性能
對於速度的真實比較,請教不斷成熟的MySQL基准套件。見10.8 使用你自己的基准。因為沒有線程創建開銷、一個較小的語法分析器、較少功能和簡單的安全性,mSQL應該在下列方面更快些:
執行重復的連接和斷開的測試,在每個連接期間運行一個非常簡單的查詢。
有很少的列和鍵的插入很簡單的表的INSERT操作。
CREATE TABLE和DROP TABLE。
在不是一個索引的一些東西上SELECT。(一個表掃描是很容易的。)
因為這些操作是如此簡單,當你有更高的啟動開銷時,很難在這些方面變得更好。在連接被建立以後,MySQL應該性能好一些。在另一方面,MySQL比mSQL(以及大多數其他的SQL實現)在下列方面更好些:
復雜的SELECT操作
檢索較大的結果(MySQL有一個更好、更快並且更安全的協議)。
有變長字符串的表,因為MySQL有更有效的並可在VARCHAR列上索引。
有很多列的表的處理。
由長記錄的表的處理。
有很多許多表達式的SELECT。
在大表上的SELECT。
同時處理很多連接。MySQL充分是完全多線程化的,每個連接有它自己的線程,這意味著沒有線程必須等待另一個線程(除非一個線程正在修改一張表,另外的線程想要存取)在mSQL中,一旦一個連接被建立了,所有其它線程必須等到第一個線程完成,不管連接正在運行的查詢是短的或是長的。當第一個連接終止時,下一個才能工作,而此時所有其它線程再次等待,等等。
聯結。如果你改變一個SELECT中的表的順序,mSQL可能變得異常地慢。在基准套件中,比MySQL要慢超過15000倍的時間。這是由於mSQL缺乏一個聯結優化器以便以最佳的順序排定表。然而,如果你把表按完全正確的順序放在mSQL2中並且WHERE是很簡單的並使用索引列,聯結將相對快些!見10.8 使用你自己的基准。
ORDER BY和GROUP BY。
DISTINCT。
使用TEXT或BLOB列。
SQL功能
GROUP BY和HAVING。mSQL根本不支持GROUP BY。MySQL支持一個有兩個HAVING和下列函數: COUNT()、AVG()、MIN()、MAX()、SUM()和STD()的完整的GROUP BY。如果SELECT從一張表中檢索,沒有其他列被檢索並且沒有WHERE子句,COUNT(*)被優化以很快地返回。 MIN()和MAX()可以取字符串參數。
帶計算的INSERT和UPDATE。MySQL能在一個INSERT或UPDATE中做計算。例如:
MySQL> UPDATE SET x=x*10+y WHERE x<20;
別名,MySQL有列的別名。
限制列名。在MySQL中,如果一個列名在用於查詢的表之間唯一的,你不必須使用完整的 合格者。
帶函數的SELECT。MySQL有很多函數(太多不能在這裡列出;見7.4 用在SELECT和WHERE子句中的函數)。
磁盤空間效率
即,你能使你的表有多小?MySQL有很精確的類型,因此你可以創建占據很小空間的表。一個有用的MySQL數據類型的例子是MEDIUMINT,它是3個字節長。如果你有100,000,000個記錄,每個記錄節省甚至一個字節也是很重要的。mSQL2有一個較有限的列類型集合,因此更難於使表更小。
穩定性
這較難客觀地評價。對於MySQL穩定性的討論,見1.5 MySQL有多麼穩定?。我們沒有mSQL穩定性的經驗,因此我們對此不能說任何東西。
價格
另一個重要的問題是許可證。MySQL有一個比mSQL更靈活的許可證,並且也不比mSQL昂貴。無論你選擇使用哪個產品,記得要至少考慮支付一個許可證或電子郵件支持的費用。(當然如果你把你出售的一個產品包括在MySQL中,你將被要求獲得一個許可證。)
Perl接口
MySQL有與mSQL基本相同Perl接口,當有一些增加的功能。
JDBC ( Java )
MySQL目前有4個JDBC驅動程序:
gwe 驅動程序:由GWE technologIEs 開發的一個Java接口(不再支持)。
jms 驅動程序:由Xiaokun Kelvin ZHU的開發的一個改進的gwe驅動程序。
twz 驅動程序:由Terrence W. Zellers 開發的一個type 4 JDBC驅動程序並用於學習目的。
mm 驅動程序:由Mark Matthews 開發的一個type 4 JDBC驅動程序。
推薦的驅動程序是twz或mm驅動程序。兩者均被報導工作出色。我們知道mSQL有一個 JDBC 驅動程序,但是我們對它有太少的經驗不能進行比較。
開發速度
MySQL有一個非常小的開發者隊伍,但是我們是非常習慣於用C和C++編碼,非常快速。因為線程、函數、GROUP BY等在mSQL中仍未實現,它有很多追趕工作要做。要想得到關於它的一些前景,你可以查看mSQL最後一年的 “HISTIRY”文件,並將它與MySQL參考書手冊的新功能小節比較(見D MySQL變遷歷史)。哪個快開發得最快應該是相當明顯的。
實用程序
mSQL和MySQL都有許多有趣的第三方工具。因為向上移植(從mSQL到MySQL)是很容易的,幾乎所有mSQL可用的有趣的應用程序也可被MySQL使用。MySQL帶有一個簡單的msql2MySQL程序修正在mSQL和MySQL使用的大多數C API函數之間拼寫差別。例如,它將msqlConnect()實例改變為MySQL_connect()。變換一個客戶程序從mSQL到MySQL通常花幾分鐘時間。
21.1.1 怎樣將mSQL的工具轉換到MySQL
根據我們的經驗,轉換諸如使用mSQL C API的msql-tcl和msqlJava工具將只花不大一小時時間,使得他們用MySQL C API工作。
轉換過程是:
在源代碼上運行外殼腳本msql2MySQL。這需要replace程序,它與MySQL一起散發。
編譯。
修正所有編譯器錯誤。
mSQL C API與MySQL C API 之間差別是:
MySQL使用一個MySQL結構作為一種連接類型(mSQL使用一個int)。
MySQL_connect()取一個指向一個MySQL結構的指針作為一個參數。很容易定義全局性定義一個或使用malloc()獲得一個。MySQL_connect()也取兩個參數指定用戶和口令。你可以為了缺省使用將這些設置為NULL,NULL。
MySQL_error()取MySQL結構作為一個參數。如果你正在移植老的代碼,只是把參數加到你的老的msql_error()編碼中。
MySQL對所有錯誤返回一個錯誤號和一條文本錯誤消息。mSQL僅返回一條文字錯誤消息。
存在某些不兼容性,因為MySQL支持從同一個進程的到服務器多個連接。
mSQL和MySQL的客戶機/服務器通訊協議有何不同
有足夠的差別使得不可能(或至少不容易)支持兩者。
它MySQL協議不同於mSQL協議的最重要的方面列在下面:
一個消息緩沖區可以包含很多結果行。
如果查詢或結果比當前緩沖區大,消息緩沖區動態地被擴大,直到一個可配置的服務器和客戶上限。
所有的包被編號以捕捉重復或丟失的包。
所有的列值以ASCII碼發送。列和行的長度以緊湊的二進制編碼(1、2或3個字節)發送。
MySQL能在未緩沖得結果中讀取(不必在客戶端存儲完整的集合)。
如果一個單獨寫/讀花了超過30秒時間,服務器關閉連接。
如果一個連接空閒8個小時,服務器關閉連接。
mSQL 2.0的SQL句法與MySQL有何不同
列類型
MySQL
有下列額外的類型(比較其他的;見7.7 CREATE TABLE句法): 、
對於一個字符串集中之一的ENUM類型。
對於一個字符串集中多個的SET類型。
對於64位整數的BIGINT類型。
MySQL也支持下列額外的類型屬性:
UNSIGNED選項。
對於整數列的ZEROFILL選項。
對於是一個PRIMARY KEY的整數列的AUTO_INCREMENT選項。見20.4.29 MySQL_insert_id()。
對所有列的DEFAULT值。
mSQL2
mSQL列類型對應於MySQL類型顯示在下面:mSQL類型 相應的MySQL類型
CHAR(len) CHAR(len)
TEXT(len) TEXT(len),len是最大長度。並且LIKE可運用。
INT INT,有很多的選項!
REAL REAL,或FLOAT。有4和8字節版本。
UINT INT UNSIGNED
DATE DATE,使用 ANSI SQL 格式而非mSQL自己的。
TIME TIME
MONEY DECIMAL(12,2),有2個小數位的定點值。
索引創建
MySQL
索引可以在表創建時用CREATE TABLE語句指定。
mSQL
在表被創建了以後,索引必須被創建,用單獨的CREATE INDEX語句。
把一個唯一標識符插入到一張表中
MySQL 使用AUTO_INCREMENT作為列類型修飾符。見20.4.29 MySQL_insert_id()。
mSQL
在一張表上創建一個SEQUENCE並且選擇_seq列。
為行獲得一個唯一標識符
MySQL 向表中增加一個PRIMARY KEY或UNIQUE鍵。
mSQL 使用_rowid列。注意_rowid可以將來改變,取決於很多因素。
得到列最後被修改的時間
MySQL 在表中增加一個TIMESTAMP列。如果你不給出列值或如果你給它一個NULL值,該列自動為INSERT或UPDATE語句設置為當前的日期和時間。
mSQL 使用_timestamp列。
NULL值的比較
MySQL MySQL遵從ANSI SQL且與NULL的比較總是NULL。
mSQL 在mSQL中,NULL = NULL是TRUE(真)。當從mSQL到MySQL移植老的代碼時,你必須將=NULL改委IS NULL,並將<>NULL改為IS NOT NULL。
字符串的比較
MySQL
通常,字符串比較以大小寫無關方式按當前字符集(缺省為ISO-8859-1 Latin1)決定的排序次序實施。如果你不喜歡這樣,聲明你的列有BINARY屬性,它使得比較根據用在MySQL服務器主機上的ASCII順序進行。
mSQL
所有的字符串比較以大小寫敏感的方式以ASCII順序排序來進行。
大小寫不敏感的搜索
MySQL
LIKE是一個大小寫不敏感或大小寫敏感的運算符,這取決於涉及的列。如果LIKE參數不以一個通配符字符開始,如有可能,MySQL則使用索引。
mSQL
使用CLIKE。
尾部空格的處理
MySQL
剝去CHAR和VARCHAR列尾部的空格。如果不希望這種行為,使用一個TEXT行列。
mSQL
保留尾部的空格。
WHERE子句
MySQL
MySQL正確地優先化任何東西(AND在OR前計算)。要想在MySQL裡得到mSQL的行為,使用括號(如下所示)。
mSQL
從左到右計算任何東西。這意味著超過3個參數的一些邏輯運算不能以任何方式表示,它也意味著當你升級到MySQL時,你必須改變一些查詢。你通過增加括號很容易做到這點。假定你有下列mSQL查詢:
MySQL> SELECT * FROM table WHERE a=1 AND b=2 OR a=3 AND b=4;
為了使MySQL像mSQL那樣計算它,你必須增加括號:
MySQL> SELECT * FROM table WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
存取控制
MySQL
有表來存儲對每個用戶、主機和數據庫的授權(許可)選項。見6.6 權限系統如何工作。
mSQL
有一個文件“mSQL.acl”,在哪裡你能為用戶授權讀/寫權限。
怎樣對比MySQL與PostgreSQL
PostgreSQL有一些更高級的功能如定義用戶類型、觸發器、規則和一些事務支持。然而,PostgreSQL 缺乏很多來自 ANSI SQL和ODBC的很多標准類型和函數。對於一個完整的限制列表及其支持或不支持哪一個類型和函數,見crash-me網頁。www.xker.com(小新技術網)
通常,PostgreSQL是比MySQL慢很多。見10.8 使用你自己的基准。這大部分是由於他們的事務系統。如果你確實需要事務或PostgreSQL提供的豐富的類型體系並且你能承受速度的損失,你應該看看 PostgreSQL。