2011年10月17日 星期一

轉載:吞嚥困難-肛門收縮法

肛門收縮法

2010年09月01日
我的母親自從坐輪椅後,身體機能逐漸退化,
從母親的病,我們學到很多寶貴的健康知識,一句話要說了再說,
人從下肢開始退化,當下肢退化到走不動,身體就會加快衰退。

母親坐輪椅後,不知從甚麼時候開始,吃飯咀嚼所花的時間越來越長,
我們沒有放在心上,細嚼慢嚥從幼兒園開始已經知道是個好習慣,
直到後來,發現這原來是吞嚥困難的徵兆,但這時候已經沒有辦法好轉。
我不知道如何讓這種病好轉,也不知道是否可以好轉,我只知道有預防的方法。

首先,不要把自己送上輪椅。
我曾經寫過,原來肛門的肌肉和嘴的肌肉相聯繫,長期坐輪椅必定影響肛門附近的肌肉。

我也寫過,有位老和尚傳了我一個「功夫」:每天早上喝第一杯水的時候,
分三十至五十小口吞下,每次吞嚥,都用力收縮肛門,這樣每天做,
可以預防吞嚥困難的毛病。這個中國民間古老的「功夫」,
竟然與日本針灸協會的理事,內田輝和醫生的研究結果不謀而合。

他在日本推廣「肛門收縮法」:
腳後跟併攏,直立,頭部與腳跟成直線,雙手下垂,手心向外翻,兩肩後縮,
使背後兩肩間形成皺紋,急速並用力收縮肛門,保持收縮狀態十秒鐘,每天做五次。

除了洗澡時,為防止血壓上沖不宜做,其他任何時間皆可,有空可以多做。

內田醫生說,這個方法可以解決腰痛和尿失禁的毛病,
可以改善頭痛、坐骨神經痛,縮小臀圍和腰圍,改善新陳代謝,臀部下垂等症狀。

2011年10月6日 星期四

[轉載]Mysql Explain 详解

http://www.cnitblog.com/aliyiyi08/archive/2008/09/09/48878.html

Mysql Explain 详解


一.语法

explain < table_name >

例如: explain select * from t3 where id=3952602;

二.explain输出解释

+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

1.id
  我的理解是SQL执行的顺利的标识,SQL从大到小的执行.

例如:
mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

很显然这条SQL是从里向外的执行,就是从id=3 向上执行.

2. select_type

就是select类型,可以有以下几种

(1) SIMPLE
简单SELECT(不使用UNION或子查询等) 例如:
mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+

(2). PRIMARY

我的理解是最外层的select.例如:

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(3).UNION

UNION中的第二个或后面的SELECT语句.例如
mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(4).DEPENDENT UNION

UNION中的第二个或后面的SELECT语句,取决于外面的查询

mysql> explain select * from t3 where id in (select id from t3 where id=3952602 union all select id from t3)  ;
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table      | type   | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3         | ALL    | NULL              | NULL    | NULL    | NULL  | 1000 | Using where              |
|  2 | DEPENDENT SUBQUERY | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
|  3 | DEPENDENT UNION    | t3         | eq_ref | PRIMARY,idx_t3_id | PRIMARY | 4       | func  |    1 | Using where; Using index |
|NULL | UNION RESULT       | <union2,3> | ALL    | NULL              | NULL    | NULL    | NULL  | NULL |                          |
+----+--------------------+------------+--------+-------------------+---------+---------+-------+------+--------------------------+

(4).UNION RESULT

UNION的结果。

mysql> explain select * from t3 where id=3952602 union all select * from t3 ;
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type  | table      | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | PRIMARY      | t3         | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
|  2 | UNION        | t3         | ALL   | NULL              | NULL    | NULL    | NULL  | 1000 |       |
|NULL | UNION RESULT | <union1,2> | ALL   | NULL              | NULL    | NULL    | NULL  | NULL |       |
+----+--------------+------------+-------+-------------------+---------+---------+-------+------+-------+

(5).SUBQUERY

子查询中的第一个SELECT.

mysql> explain select * from t3 where id = (select id from t3 where id=3952602 )  ;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+
|  1 | PRIMARY     | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |             |
|  2 | SUBQUERY    | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       |       |    1 | Using index |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------------+

(6).  DEPENDENT SUBQUERY

子查询中的第一个SELECT,取决于外面的查询

mysql> explain select id from t3 where id in (select id from t3 where id=3952602 )  ;
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
| id | select_type        | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra                    |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+
|  1 | PRIMARY            | t3    | index | NULL              | PRIMARY | 4       | NULL  | 1000 | Using where; Using index |
|  2 | DEPENDENT SUBQUERY | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 | Using index              |
+----+--------------------+-------+-------+-------------------+---------+---------+-------+------+--------------------------+


(7).DERIVED

派生表的SELECT(FROM子句的子查询)

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+


3.table

显示这一行的数据是关于哪张表的.
有时不是真实的表名字,看到的是derivedx(x是个数字,我的理解是第几步执行的结果)

mysql> explain select * from (select * from ( select * from t3 where id=3952602) a) b;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | <derived3> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  3 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

4.type

这列很重要,显示了连接使用了哪种类别,有无使用索引.
从最好到最差的连接类型为const、eq_reg、ref、range、indexhe和ALL

(1).system

这是const联接类型的一个特例。表仅有一行满足条件.如下(t3表上的id是 primary key)

mysql> explain select * from (select * from t3 where id=3952602) a ;
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
| id | select_type | table      | type   | possible_keys     | key     | key_len | ref  | rows | Extra |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+
|  1 | PRIMARY     | <derived2> | system | NULL              | NULL    | NULL    | NULL |    1 |       |
|  2 | DERIVED     | t3         | const  | PRIMARY,idx_t3_id | PRIMARY | 4       |      |    1 |       |
+----+-------------+------------+--------+-------------------+---------+---------+------+------+-------+

(2).const

表最多有一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被优化器剩余部分认为是常数。const表很快,因为它们只读取一次!

const用于用常数值比较PRIMARY KEY或UNIQUE索引的所有部分时。在下面的查询中,tbl_name可以用于const表:
SELECT * from tbl_name WHERE primary_key=1;
SELECT * from tbl_name WHERE primary_key_part1=1和 primary_key_part2=2;

例如:
mysql> explain select * from t3 where id=3952602;
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys     | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | t3    | const | PRIMARY,idx_t3_id | PRIMARY | 4       | const |    1 |       |
+----+-------------+-------+-------+-------------------+---------+---------+-------+------+-------+


(3). eq_ref

对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY。

eq_ref可以用于使用= 操作符比较的带索引的列。比较值可以为常量或一个使用在该表前面所读取的表的列的表达式。

在下面的例子中,MySQL可以使用eq_ref联接来处理ref_tables:

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如
mysql> create unique index  idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type   | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL    | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | eq_ref | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+--------+-------------------+-----------+---------+----------------------+------+-------+

(4).ref

对 于每个来自于前面的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联接只使用键的最左边的前缀,或如果键不是UNIQUE或PRIMARY KEY(换句话说,如果联接不能基于关键字选择单个行的话),则使用ref。如果使用的键仅仅匹配少量行,该联接类型是不错的。

ref可以用于使用=或<=>操作符的带索引的列。

在下面的例子中,MySQL可以使用ref联接来处理ref_tables:

SELECT * FROM ref_table WHERE key_column=expr;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column=other_table.column;

SELECT * FROM ref_table,other_table
  WHERE ref_table.key_column_part1=other_table.column
    AND ref_table.key_column_part2=1;

例如:

mysql> drop index idx_t3_id on t3;
Query OK, 1000 rows affected (0.03 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> create index idx_t3_id on t3(id) ;
Query OK, 1000 rows affected (0.04 sec)
Records: 1000  Duplicates: 0  Warnings: 0

mysql> explain select * from t3,t4 where t3.id=t4.accountid;
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
| id | select_type | table | type | possible_keys     | key       | key_len | ref                  | rows | Extra |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
|  1 | SIMPLE      | t4    | ALL  | NULL              | NULL      | NULL    | NULL                 | 1000 |       |
|  1 | SIMPLE      | t3    | ref  | PRIMARY,idx_t3_id | idx_t3_id | 4       | dbatest.t4.accountid |    1 |       |
+----+-------------+-------+------+-------------------+-----------+---------+----------------------+------+-------+
2 rows in set (0.00 sec)

(5).  ref_or_null

该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。

在下面的例子中,MySQL可以使用ref_or_null联接来处理ref_tables:

SELECT * FROM ref_table
WHERE key_column=expr OR key_column IS NULL;

(6). index_merge

该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。

例如:
mysql> explain select * from t4 where id=3952602 or accountid=31754306 ;
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
| id | select_type | table | type        | possible_keys              | key                        | key_len | ref  | rows | Extra                                                |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
|  1 | SIMPLE      | t4    | index_merge | idx_t4_id,idx_t4_accountid | idx_t4_id,idx_t4_accountid | 4,4     | NULL |    2 | Using union(idx_t4_id,idx_t4_accountid); Using where |
+----+-------------+-------+-------------+----------------------------+----------------------------+---------+------+------+------------------------------------------------------+
1 row in set (0.00 sec)

(7). unique_subquery

该类型替换了下面形式的IN子查询的ref:

value IN (SELECT primary_key FROM single_table WHERE some_expr)
unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。

(8).index_subquery

该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引:

value IN (SELECT key_column FROM single_table WHERE some_expr)

(9).range

只检索给定范围的行,使用一个索引来选择行。key列显示使用了哪个索引。key_len包含所使用索引的最长关键元素。在该类型中ref列为NULL。

当使用=、<>、>、>=、<、<=、IS NULL、<=>、BETWEEN或者IN操作符,用常量比较关键字列时,可以使用range

mysql> explain select * from t3 where id=3952602 or id=3952603 ;
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys     | key       | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
|  1 | SIMPLE      | t3    | range | PRIMARY,idx_t3_id | idx_t3_id | 4       | NULL |    2 | Using where |
+----+-------------+-------+-------+-------------------+-----------+---------+------+------+-------------+
1 row in set (0.02 sec)

(10).index

该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。

当查询只使用作为单索引一部分的列时,MySQL可以使用该联接类型。

(11). ALL

对于每个来自于先前的表的行组合,进行完整的表扫描。如果表是第一个没标记const的表,这通常不好,并且通常在它情况下很差。通常可以增加更多的索引而不要使用ALL,使得行能基于前面的表中的常数值或列值被检索出。


5.possible_keys

possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。

如果该列是NULL,则没有相关的索引。在这种情况下,可以通过检查WHERE子句看是否它引用某些列或适合索引的列来提高你的查询性能。如果是这样,创造一个适当的索引并且再次用EXPLAIN检查查询

6. key

key列显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。

7.key_len

key_len列显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
使用的索引的长度。在不损失精确性的情况下,长度越短越好

8. ref

ref列显示使用哪个列或常数与key一起从表中选择行。

9. rows

rows列显示MySQL认为它执行查询时必须检查的行数。

10. Extra

该列包含MySQL解决查询的详细信息,下面详细.

(1).Distinct
一旦MYSQL找到了与行相联合匹配的行,就不再搜索了

(2).Not exists
MYSQL优化了LEFT JOIN,一旦它找到了匹配LEFT JOIN标准的行,

就不再搜索了

(3).Range checked for each

Record(index map:#)
没有找到理想的索引,因此对于从前面表中来的每一个行组合,MYSQL检查使用哪个索引,并用它来从表中返回行。这是使用索引的最慢的连接之一

(4).Using filesort
看到这个的时候,查询就需要优化了。MYSQL需要进行额外的步骤来发现如何对返回的行排序。它根据连接类型以及存储排序键值和匹配条件的全部行的行指针来排序全部行

(5).Using index
列数据是从仅仅使用了索引中的信息而没有读取实际的行动的表返回的,这发生在对表的全部的请求列都是同一个索引的部分的时候

(6).Using temporary
看到这个的时候,查询需要优化了。这里,MYSQL需要创建一个临时表来存储结果,这通常发生在对不同的列集进行ORDER BY上,而不是GROUP BY上

(7).Using where
使用了WHERE从句来限制哪些行将与下一张表匹配或者是返回给用户。如果不想返回表中的全部行,并且连接类型ALL或index,这就会发生,或者是查询有问题

[轉載]MySQL查詢優化系列講座之查詢優化器

http://imnanako.pixnet.net/blog/post/8344105-%5B%E8%BD%89%E8%BC%89%5Dmysql%E6%9F%A5%E8%A9%A2%E5%84%AA%E5%8C%96%E7%B3%BB%E5%88%97%E8%AC%9B%E5%BA%A7%E4%B9%8B%E6%9F%A5%E8%A9%A2%E5%84%AA%E5%8C%96%E5%99%A8
[轉載]MySQL查詢優化系列講座之查詢優化器

當你提交一個查詢的時候,MySQL會分析它,看是否可以做一些優化使處理該查詢的速度更快。這一部分將介紹查詢優化器是如何工作的。如果你想知道MySQL採用的優化手段,可以查看MySQL參考手冊。

當然,MySQL查詢優化器也利用了索引,但是它也使用了其他一些資訊。例如,如果你提交如下所示的查詢,那麼無論數據表有多大,MySQL執行它的速度都會非常快:

SELECT * FROM tbl_name WHERE 0;

在這個例子中,MySQL查看WHERE子句,認識到沒有符合查詢條件的數據行,因此根本就不考慮搜索數據表。你可以通過提供一個EXPLAIN語句看 到這種情況,這個語句讓MySQL顯示自己執行的但實際上沒有真正地執行的SELECT查詢的一些資訊。如果要使用EXPLAIN,只需要在 EXPLAIN單詞放在SELECT語句的前面:

mysql> EXPLAIN SELECT * FROM tbl_name WHERE 0\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: NULL
type: NULL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: NULL
Extra: Impossible WHERE

通常情況下,EXPLAIN返回的資訊比上面的資訊要多一些,還包括用於掃描數據表的索引、使用的聯結類型、每張數據表中估計需要檢查的數據行數量等非空(NULL)資訊。

優化器是如何工作的

MySQL查詢優化器有幾個目標,但是其中最主要的目標是盡可能地使用索引,並且使用最嚴格的索引來消除盡可能多的數據行。你的最終目標是提交 SELECT語句搜尋數據行,而不是排除數據行。優化器試圖排除數據行的原因在於它排除數據行的速度越快,那麼找到與條件匹配的數據行也就越快。如果能夠 首先進行最嚴格的測試,查詢就可以執行地更快。假設你的查詢檢驗了兩個數據列,每個列上都有索引:

SELECT col3 FROM mytable
WHERE col1 = ’some value’ AND col2 = ’some other value’;

假設col1上的測試匹配了900個數據行,col2上的測試匹配了300個數據行,而同時進行的測試只得到了30個數據行。先測試Col1會有900 個數據行,需要檢查它們找到其中的30個與col2中的值匹配記錄,其中就有870次是失敗了。先測試col2會有300個數據行,需要檢查它們找到其中 的30個與col1中的值匹配的記錄,只有270次是失敗的,因此需要的計算和磁片I/O更少。其結果是,優化器會先測試col2,因為這樣做開銷更小。

你可以通過下面一個指導幫助優化器更好地利用索引:

儘量比較數據類型相同的數據列。當你在比較操作中使用索引數據列的時候,請使用數據類型相同的列。相同的數據類型比不同類型的性能要高一些。例 如,INT與BIGINT是不同的。CHAR(10)被認為是CHAR(10)或VARCHAR(10),但是與CHAR(12)或 VARCHAR(12)不同。如果你所比較的數據列的類型不同,那麼可以使用ALTER TABLE來修改其中一個,使它們的類型相匹配。

盡可能地讓索引列在比較運算式中獨立。如果你在函數調用或者更複雜的算術運算式條件中使用了某個數據列,MySQL就不會使用索引,因為它必須計算出每個數據行的運算式值。有時候這種情況無法避免,但是很多情況下你可以重新編寫一個查詢讓索引列獨立地出現。

下面的WHERE子句顯示了這種情況。它們的功能相同,但是對於優化目標來說就有很大差異了:

WHERE mycol < 4 / 2
WHERE mycol * 2 < 4

對於第一行,優化器把運算式4/2簡化為2,接著使用mycol上的索引來快速地搜尋小于2的值。對於第二個運算式,MySQL必須檢索出每個數據行的 mycol值,乘以2,接著把結果與4進行比較。在這種情況下,不會使用索引。數據列中的每個值都必須被檢索到,這樣才能計算出比較運算式左邊的值。

我們看另外一個例子。假設你對date_col列進行了索引。如果你提交一條如下所示的查詢,就不會使用這個索引:

SELECT * FROM mytbl WHERE YEAR(date_col) < 1990;

這個運算式不會把1990與索引列進行比較;它會把1990與該數據列計算出來的值比較,而每個數據行都必須計算出這個值。其結果是,沒有使用 date_col上的索引,因為執行這樣的查詢需要全表掃描。怎麼解決這個問題呢?只需要使用文本日期,接著就可以使用date_col上的索引來搜尋列 中匹配的值了:

WHERE date_col < ’1990-01-01’

但是,假設你沒有特定的日期。你可能希望找到一些與今天相隔固定的幾天的日期的記錄。表達這種類型的比較有很多種方法--它們的效率並不同。下面就有三種:

WHERE TO_DAYS(date_col) - TO_DAYS(CURDATE()) < cutoff
WHERE TO_DAYS(date_col) < cutoff + TO_DAYS(CURDATE())
WHERE date_col < DATE_ADD(CURDATE(), INTERVAL cutoff DAY)

對於第一行,不會用到索引,因為每個數據行都必須檢索以計算出TO_DAYS(date_col)的值。第二行要好一些。Cutoff和 TO_DAYS(CURDATE())都是常量,因此在處理查詢之前,比較運算式的右邊可以被優化器一次性計算出來,而不需要每個數據行都計算一次。但是 date_col列仍然出現在函數調用中,它阻止了索引的使用。第三行是這幾個中最好的。同樣,在執行查詢之前,比較運算式的右邊可以作為常量一次性計算 出來,但是現在它的值是一個日期。這個值可以直接與date_col值進行比較,再也不需要轉換成天數了。在這種情況下,會使用索引。

在LIKE模式的開頭不要使用通配符。有些字符串搜索使用如下所示的WHERE子句:

WHERE col_name LIKE ’%string%’

如果你希望找到那些出現在數據列的任何位置的字符串,這個語句就是對的。但是不要因為習慣而簡單地把"%"放在字符串的兩邊。如果你在搜尋出現在數據列 開頭的字符串,就刪掉前面的"%"。假設你要搜尋那些類似MacGregor或MacDougall等以"Mac"開頭的名字。在這種情況下,WHERE 子句如下所示:

WHERE last_name LIKE ’Mac%’

優化器查看該模式中詞首的文本,並使用索引找到那些與下面的運算式匹配的數據行。下面的運算式是使用last_name索引的另一種形式:

WHERE last_name >= ’Mac’ AND last_name < ’Mad’

這種優化不能應用於使用了REGEXP操作符的模式匹配。REGEXP運算式永遠不會被優化。

幫助優化器更好的判斷索引的效率。在默認情況下,當你把索引列的值與常量進行比較的時候,優化器會假設鍵值在索引內部是均勻分佈的。在決定進行常量比較 是否使用索引的時候,優化器會快速地檢查索引,估計出會用到多少個實體(entry)。對應MyISAM、InnoDB和BDB數據表來說,你可以使用 ANALYZE TABLE讓伺服器執行對鍵值的分析。它會為優化器提供更好的資訊。

使用EXPLAIN驗證優化器的操作。EXPLAIN語句可以告訴你是否使用了索引。當你試圖用另外的方式編寫語句或檢查添加索引是否會提高查詢執行效率的時候,這些資訊對你是有幫助的。

在必要的時候給優化器一些提示。正常情況下,MySQL優化器自由地決定掃描數據表的次序來最快地檢索數據行。在有些場合中優化器沒有作出最佳選擇。如 果你察覺這種現象發生了,就可以使用STRAIGHT_JOIN關鍵字來重載優化器的選擇。帶有STRAIGHT_JOIN的聯結類似于交叉聯結,但是強 迫數據表按照FROM子句中指定的次序來聯結。

在SELECT語句中有兩個地方可以指定STRAIGHT_JOIN。你可以在SELECT關鍵字和選擇列表之間的位置指定,這樣會對語句中所有的交叉聯結產生影響;你也可以在FROM子句中指定。下面的兩個語句功能相同:

SELECT STRAIGHT_JOIN ... FROM t1, t2, t3 ... ;
SELECT ... FROM t1 STRAIGHT_JOIN t2 STRAIGHT_JOIN t3 ... ;

分別在帶有STRAIGHT_JOIN和不帶STRAIGHT_JOIN的情況下運行這個查詢;MySQL可能因為什麼原因沒有按照你認為最好的次序使用索引(你可以使用EXPLAIN來檢查MySQL處理每個語句的執行計劃)。

你還可以使用FORCE INDEX、USE INDEX或IGNORE INDEX來指導伺服器如何使用索引。

利用優化器更加完善的區域。MySQL可以執行聯結和子查詢,但是子查詢是最近才支援的,是在MySQL 4.1中添加的。因而在很多情況下,優化器對聯結操作的調整比對子查詢的調整要好一些。當你的子查詢執行地很慢的時候,這就是一條實際的提示。有一些子查 詢可以使用邏輯上相等的聯結來重新表達。在可行的情況下,你可以把子查詢重新改寫為聯結,看是否執行地快一些。

測試查詢的備用形 式,多次運行。當你測試查詢的備用形式的時候(例如,子查詢與等同的聯結操作對比),每種方式都應該多次運行。如果兩種形式都只運行了一次,那麼你通常會 發現第二個查詢比第一個快,這是因為第一個查詢得到的資訊仍然保留在緩存中,以至於第二個查詢沒有真正地從磁片上讀取數據。你還應該在系統負載相對平穩的 時候運行查詢,以避免系統中其他的事務影響結果。

避免過度地使用MySQL自動類型轉換。MySQL會執行自動的類型轉換,但是如果你能夠避免這種轉換操作,你得到的性能就更好了。例如,如果num_col是整型數據列,那麼下面這些查詢將返回相同的結果:

SELECT * FROM mytbl WHERE num_col = 4;
SELECT * FROM mytbl WHERE num_col = ’4’;

但是第二個查詢涉及到了類型轉換。轉換操作本身為了把整型和字符串型轉換為雙精度型進行比較,使性能惡化了。更嚴重的情況是,如果num_col是索引的,那麼涉及到類型轉換的比較操作不會使用索引。

[轉載]MySQL的查詢時間(log-slow-queries)

http://homeserver.com.tw/mysql/mysql%E7%9A%84%E6%9F%A5%E8%A9%A2%E6%99%82%E9%96%93log-slow-queries/




作者: 丫忠
• 星期四, 四月 01st, 2010
MySQL資料庫的query查詢時間往往取決於【是否建立索引】、【資料量多寡】、【query查詢的方法】…等,然而【是否建立索引】的因素卻是影響query查詢時間最重要的因素之一。
舉個例子:如果你的Table(User)中有一個name的欄位,當你要查詢姓氏為’林’的使用者,通常你會這樣下SQL語法
SELECT * FROM User WHERE name like ‘%林%’;
如此,一般而言你會將name這個欄位加入index索引中,否則當資料量大時,query時間的快慢就會明顯出現差異了。
當完成了一個網站後,程式中針對MySQL查詢(query)的次數那麼多,那要如何找出query查詢時間較長的語法呢?其實在my.cnf設定檔中(一般在/etc/my.cnf),已經提供了參數可以直接產生log記錄檔案,讓管理者可以很清楚了解到那些查詢(query)的語法花費較多的時間。
請在my.cnf設定檔中,找到[mysqld]標籤,在此標籤下面加上:
log-slow-queries = /path/slow-query.log #slow query記錄檔的路儲存路徑
long_query_time = 2 #query超過2秒時,則會記錄
log-queries-not-using-indexes #沒有索引的記錄,則會記錄
設定完成my.cnf後,請記得要重新啟動MySQL
其中,log-slow-queries記錄檔的儲存路徑,這個目錄一定要是mysql使用者可以寫入權限的位置,因為slow-query.log記錄檔是由mysql使用者去執行寫入;否則,會造成記錄檔案無法產生的情況,這個問題是最常發生,請切記!

[轉載]MySQL最佳化分析指令EXPLAIN

http://homeserver.com.tw/mysql/mysql%E6%9C%80%E4%BD%B3%E5%8C%96%E5%88%86%E6%9E%90%E6%8C%87%E4%BB%A4explain/



作者: 丫忠
• 星期四, 四月 01st, 2010
上一篇丫忠介紹了 MySQL的查詢時間記錄 後,除了從記錄檔中去分析查詢時間外;另外,還有一個非常棒的指令可以用來分析SELECT指令在MySQL中的執行情況,那就是 EXPLAIN
EXPLAIN 顯示的訊息可以用來幫助索引和查出最佳化的查詢語法。
EXPLAIN 使用的方式:
只要在SELECT語法前面加上 EXPLAIN 指令即可。
例如:EXPLAIN SELECT * FROM website WHERE url=’http://homeserver.com.tw’;
執行結果畫面如下:
其中針對EXPLAIN的欄位說明如下:
table:關連到的資料表(Table)會顯示在此。
type:顯示使用了何種類型。從最優至最差的類型為const、eq_reg、ref、range、indexhe、ALL。
possible_keys:顯示可能使用到的索引。此為從WHERE語法中選擇一個適合的欄位名稱。
key:實際使用到的索引。如果為NULL,則是沒有使用索引。
key_len:使用索引的長度。長度越短 準確性越高。
ref:顯示那一列的索引被使用。一般是一個常數(const)。
rows:MySQL用來返回資料的筆數。
Extra:MySQL用來解析額外的查詢訊息。如果此欄位的值為:Using temporary和Using filesort,表示MySQL無法使用索引。
Extra為MySQL用來解析額外的查詢訊息,其中欄位值所代表的意義如下:
Distinct:當MySQL找到相關連的資料時,就不再搜尋。
Not exists:MySQL優化 LEFT JOIN,一旦找到符合的LEFT JOIN資料後,就不再搜尋。
Range checked for each Record(index map:#):無法找到理想的索引。此為最慢的使用索引。
Using filesort:當出現這個值時,表示此SELECT語法需要優化。因為MySQL必須進行額外的步驟來進行查詢。
Using index:返回的資料是從索引中資料,而不是從實際的資料中返回,當返回的資料都出現在索引中的資料時就會發生此情況。
Using temporary:同Using filesort,表示此SELECT語法需要進行優化。此為MySQL必須建立一個暫時的資料表(Table)來儲存結果,此情況會發生在針對不同的資料進行ORDER BY,而不是GROUP BY。
Using where:使用WHERE語法中的欄位來返回結果。
System:system資料表,此為const連接類型的特殊情況。
Const:資料表中的一個記錄的最大值能夠符合這個查詢。因為只有一行,這個值就是常數,因為MySQL會先讀這個值然後把它當做常數。
eq_ref:MySQL在連接查詢時,會從最前面的資料表,對每一個記錄的聯合,從資料表中讀取一個記錄,在查詢時會使用索引為主鍵或唯一鍵的全部。
ref:只有在查詢使用了非唯一鍵或主鍵時才會發生。
range:使用索引返回一個範圍的結果。例如:使用大於>或小於<查詢時發生。
index:此為針對索引中的資料進行查詢。
ALL:針對每一筆記錄進行完全掃描,此為最壞的情況,應該盡量避免

2011年4月21日 星期四

[轉載]Ethernet Wifi Adapter

Netgear WNCE2001
種類: Universal WiFi Internet Adapter
規格: 802.11b/g/n
around $480
http://www.price.com.hk/product.php?p=125793
http://www.reviewguy.net/gadgets/netgear-wnce2001.html
http://www.netgear.com/home/products/wireless-adapters/high-performance/WNCE2001.aspx

Buffalo Portable Ethernet Converter – WLAE-AG300N
http://www.technicstoday.com/2010/09/buffalo-portable-ethernet-converter-wlae-ag300n/

2010年11月12日 星期五

[轉載]Web 3.0世界 消費者話事

http://www.hket.com/eti/article/c71dc882-4fa0-4de8-b9d9-69b76645a174-036875?category=facebook


 Web 3.0世界 消費者話事
未來學家:任何帳戶均可攜
科技主導未來,當手機市場被iPhone牽着鼻子走,以為10年之後會出到第N代iPhone?被《哈佛商業評論》評為「Man about the Internet」、早於1994年博客紀元盤古初開時已寫Blog的David Siegel,接受本報越洋專訪時預言:「到時已不需要iPhone,若蘋果依照現時經營途徑,300間專門店將於2025年全部消失!」互聯網由Web 1.0進化至目前的Web 3.0,商業軸心已逐步由Push變Pull,發球權落在顧客身上,銀行、醫療戶口將如手機號碼一樣可攜。下周一於數碼港「Web 3.0亞洲高峰會」開壇的Siegel,將教本地商家如何在科技新浪裏淘金。
Web 1.0及Web 2.0資訊大爆炸,今天全球每日產生500 Exabytes數據量,若將之實物化,即相等於80億公里,地球與太陽來回50次,而2015年的數據量將是目前的20倍。「99%都是推動資訊 (Pushing Information),全球每年有10兆美元生意受影響。」
傳媒零售走得前
舉一個簡單例子區分Push和Pull資訊,Siegel嘗試在Google搜尋「Venice的天氣」,網頁根據關鍵字,列出多個無關的網頁,網民要在 「硬塞」的資訊海裏再逐一點擊。在新一代智能搜尋器WolframAlpha鍵入相同問題,Siegel將「Venice」定點為美國城市Venice, 搜尋器便詳報當地目前、過去及未來的天氣歷史,資訊到位,是Pull的一大示範。
Web 3.0扭轉商業遊戲規則,贏家法則是:「讓你的顧客決定,何時何地、用哪些工具來取得資訊。」Siegel強調其破壞力驚人,但商家無得揀,若能順着這一 浪,企業成本可減高達20%。在眾多行業當中,他認為目前以傳媒、零售及物業走得較前,醫療及財務界因受制法規,發展較慢,製造業則是一匹黑馬。「最明顯 是電視革命帶來網上重溫(On-demand Webcast),觀眾毋須再根據電視節目表,坐定定在電視機面前睇節目,何時停看、重看都能自由控制。至於製造業,則可在生產綫上加入個別消費者的要 求,做到大量個人化(Mass Customization)。」
營運關係管理成關鍵
值得注意的是,未來一切個人資訊,包括興趣、健康狀況、財務帳戶、家庭狀況都會存在每個人在網絡上的Data Locker(見另文)。資訊跟人走,可攜服務會由目前的手機數碼,蔓延至財務及醫療帳戶,「戶口可攜將是企業表現的一大指標。假設消費者不滿意這間銀行 服務,可將整個戶口搬到另一家銀行。在新的遊戲規則下,營運關係管理(Vendor Relationship Management)尤其重要。」
Siegel認為,消費者數據是未來商業流通「貨幣」,與其一窩峰做社交網絡市務,不如現在就開始將無規律的數據整合成有用資訊。他強烈建議企業聘請一位 市務科技總監(Chief Marketing Technology Officer),「其制定的策略,將決定企業成敗。」
----------------------------------
Web 3.0應用
零售:德國Metro Group超市引入智能購物車,消費者每選一件貨品,購物車掃瞄貨品上的RFID,就會在屏幕顯示購物清單、優惠,並計算消費額。消費者可用手機銀行、信 用卡,甚至指紋來付款。貨架會偵測到貨架哪件貨被選購,並追蹤到產品目的地,超市藉此分析消費行為。
電訊:看病、消費、唱K後,Data Locker資訊都會實時更新。頻寬(Broadband)是網絡的心臟,Siegel指,高端智能手機及Netbook等會大劈價,未來用甚麼工具都不 重要,「iPhone、BlackBerry、電子書,通通會被網絡屏幕取代。手腕、座駕裏的儀錶板或家裏的牆壁,都可連接網絡。」建議電訊商看準這時 機。
醫療:外國研究指,5成長期病患者於服藥1年後會停藥,堅持服藥的只有5%。Aardex Group推出名為MEMS(MicroElectrical Mechanical Systems)的智能藥盒,LCD屏幕會顯示病人服藥情況,並將資訊傳送到醫療系統,給醫生診斷。即使病人不覆診,醫生也可根據其病情來開藥。目前已有 40萬病人使用。
大廈:美國多楝大廈已安裝感應器,連接Pachube.com,可偵測天氣、交通、大廈維修項目、保安、能源消耗等狀況,大廈與大廈之間可互相「對話」, 交換資訊。智能大廈也懂得因應維修項目,向供應商訂貨。在物聯網(Internet of Things)下,這種毋須人手處理的機器對機器(Machine2Machine)溝通,將主宰下一個10年。
撰文:吳曉怡