<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2011年8月20日

    Innodb存儲

    表空間是邏輯存放所有數據的地方,默認情況下會共享一個表空間——ibdata1,但如果把innodb_file_per_table=ON后每張表可以單獨放到一個表空間內,但還是有很多數據保存在共享的表ibdata1中,如undo信息等。

     

    表空間由各種段(segment)組成,常見的段有數據段、索引段等。Innodb是索引組織的,數據段就是clustered index的葉結點。需要注意的是,不是每個對象都有段。

     

    (extend)是由64個連續的頁組成,每個頁(page)固定為16KB,所以每個區總共為1M。頁是innodb最小的磁盤管理單位。

     

    Innodb是按行進行存放的,每個區最少可以保存2條記錄,否則就成鏈式結構了。每行數據除了自定義列以外,還會增加事務id和回滾指針列。如果沒有定義primary key也沒有not nullunique,則會增加6字節的RowId列作為主鍵。
            
                圖片來自:http://www.cnblogs.com/chjw8016/archive/2011/03/08/1976891.html

    Innodb表的限制

            一個表不能包含超過1000列。

      內部最大鍵長度是3500字節,但MySQL自己限制這個到1024字節。

      除了VARCHAR, BLOBTEXT列,最大行長度稍微小于數據庫頁的一半。即,最大行長度大約8000字節。LONGBLOBLONGTEXT列必須小于4GB, 總的行長度,頁包括BLOBTEXT列,必須小于4GBInnoDB在行中存儲VARCHARBLOBTEXT列的前768字節,余下的存儲的分散的頁中。

    雖然InnoDB內部地支持行尺寸大于65535,你不能定義一個包含VARCHAR列的,合并尺寸大于65535的行。

    ·                mysql> CREATE TABLE t (a VARCHAR(8000), b VARCHAR(10000),

    ·                    -> c VARCHAR(10000), d VARCHAR(10000), e VARCHAR(10000),

    ·                    -> f VARCHAR(10000), g VARCHAR(10000));

    ·                ERROR 1118 (42000): Row size too large. The maximum row size for the

    ·                used table type, not counting BLOBs, is 65535. You have to change some

    ·                columns to TEXT or BLOBs

     在一些更老的操作系統上,數據文件必須小于2GB

     InnoDB日志文件的合并尺寸必須小于4GB

    最小的表空間尺寸是10MB。最大的表空間尺寸是4,000,000,000個數據庫頁(64TB)。這也是一個表的最大尺寸。

     InnoDB表不支持FULLTEXT索引

     

    Innodb索引

    默認情況下Memory使用存儲hash索引,但也支持b+tree索引。Hash索引只用于=或者<=>的等式比較,不能用來加速order by操作,只能通過關鍵字來搜索一行。innodb只支持b+樹索引,進一步分為clustered index 與 secondary index。在一次查詢中,只能使用一個索引。

            

    Innodb是索引組織表,clustered index的葉結點保存著整行的數據。如果,定義了primary key,則clustered index就是primary key的索引;如果沒有定義primary key mysql會選中第一個僅有not null列的unique索引作為主鍵,并把此索引當作clustered index使用;如果沒找到這樣的列,innodb會創建一個6字節的RowId作為主鍵。所以每張表有且只有一個clustered index

     

             Secondary index的葉結點不包括行的全部數據,包含鍵值以外還包括一個bookmark,可以告訴innodb到什么地方可以找到相對應的完整行數據,還保存了主鍵的健值。Secondary index包含主鍵,但不包含完整的行數據,所以innodb總是會先從secondary index的葉節點判斷是否能得到所需的數據。如,

             Create table t(a int, b varchar(20), primary key(a), key(b));

    Explain select * from t;

             會發現mysql選擇了索引b,而不是a.

    復合索引

             復合索引是在多列(>=2)上建立的索引,又叫多列索引或聯合索引。Innodb中的復合索引也是b+ tree結構。索引的數據包含多列(col1, col2, col3…),在索引中依次按照col1, col2, col3排序。如(1, 2), (1, 3),(2,0)…

     

             使用復合索引要充分利用最左前綴原則,顧名思義,就是最左優先。如創建索引ind_col1_col2(col1, col2),那么在查詢where col1 = xxx and col2 = xx或者where col1 = xxx都可以走ind_col1_col2索引。

    在創建多列索引時,要根據業務需求,where子句中使用最頻繁且過濾效果好的的一列放在最左邊。

    索引操作

             可以通過DML語句操作innodb索引。因為innodb是索引組織的表,對索引的操作會造成鎖表,先生成一張臨時表,將數據從原始表中寫到臨時表,再將原始表刪除,最后將臨時表表名改為原始表表名!因增加、刪除、修改字段會對主索引產生影響,所以也會鎖表。對secondary indexInnodb plugin開始,支持快速索引創建的方法,在創建的過程中不需要重建表,所以速度會很快,同時引擎會在表上加S鎖,在創建過程中只能進行讀操作。

    索引設計原則

    1.       搜索的索引列,不一定是所要選擇的列。也就是說,最適合索引的列是出現在where子句中的列,或者連接子句中指定的列,而不是出現在select關鍵字后的選擇列表中的列。

    2.       使用唯一索引。考慮某列的分布,索引的列的基數越大,索引的效果越好。例如,對性別M/F列做索引沒多大用處。

    3.       使用短索引。如果是對字符串進行索引,如果有可能應該指定前綴長度。

    4.       利用最左前綴。盡量將使用頻繁且過濾效果好的字段放“左邊”

    5.       不要過度索引。

    6.       Innodb默認會按照一定的順序保存數據,如果明確定義了主鍵,則按照主鍵順序保存。如果沒有主鍵,但有唯一索引,就按照唯一索引的順序保存。如果有幾個列都是唯一的,都可以作為主鍵的時候,為了提高查詢效率,應選擇最常用訪問的列作為主鍵。另外,innodbsecondary index都會保存主鍵的鍵值,所有主鍵要盡可能選擇較短的數據類型。可以看出,應當盡量避免對主鍵的修改。經過dba的測試,保證主鍵的遞增可以提高插入性能。

     

    Mysql如何使用索引

    1.       對于創建的多列索引,只要查詢的條件中用到了最左邊的列,索引一般就會被使用。

    2.       對于使用like的查詢,后面如果是常量并且只有%號不在第一個字符,索引才可能被使用。

    3.       如果對大文本進行搜索,應該使用全文索引,而不是使用like ‘%...%’. 但不幸的是innodb不支持全文索引。

    4.       如果列名是索引,使用 index_column is null將使用索引。Oracle是不行的。

    5.       如果mysql估計使用索引比全表掃描更慢,最不會使用索引。

    6.       如果使用memory/head表并且where條件中不使用”=”進行索引列,那么不會用到索引。Head表只有在”=”的時候才會使用索引。

    7.       or分割開的條件,如果or前的條件中的列有索引,而后面列中沒有索引,那么涉及到的索引都不會被用到。

    8.       不是多列索引的第一部分不會走索引。

    9.       %開始的like不會走索引

    10.   如果列是字符串,那么一定要在where條件中把字符串常量值用引號引起來,否則不能走索引。因為,mysql默認把輸入的常量值進行轉換以后才進行檢索。

    11.   經過普通運算或函數運算后的索引字段不能使用索引

    12.   不等于操作不能使用索,<>not in

    13.   Order by 優化:某些情況下,mysql可以使用一個索引滿足order by,而不需要額外的排序。Where條件與order by 使用相同的索引,并且order by的順序和索引順序相同,并且order by的字段都是升序或者都是降序。

    SELECT * FROM t1 ORDER BY key_part1,key_part2,... ;

    SELECT * FROM t1 WHERE key_part1=1 ORDER BY key_part1 DESC, key_part2

    DESC;

    SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 DESC;

    但是以下情況不使用索引:

    SELECT * FROM t1 ORDER BY key_part1 DESC, key_part2 ASC

    --order by 的字段混合 ASC DESC

    SELECT * FROM t1 WHERE key2=constant ORDER BY key1

    -- 用于查詢行的關鍵字與 ORDER BY 中所使用的不相同

    SELECT * FROM t1 ORDER BY key1, key2

    -- 對不同的關鍵字使用 ORDER BY     

     

    可以使用explain查看sql的執行計劃。

    posted @ 2011-12-17 16:36 happyenjoylife 閱讀(10248) | 評論 (2)編輯 收藏
    原文:
    http://stas-blogspot.blogspot.com/2010/03/java-bridge-methods-explained.html

    Bridge methods in Java are synthetic methods, which are necessary to implement some of Java language features. The best known samples are covariant return type and a case in generics when erasure of base method's arguments differs from the actual method being invoked.

    Have a look at following example:

    public class SampleOne {
    public static class A<T> {
    public T getT() {
    return null;
    }
    }

    public static class  B extends A<String> {
    public String getT() {
    return null;
    }
    }
    }

    Which in reality is just an example of covariant return type and after erasure will look like following snippet:

    public class SampleOne {
    public static class A {
    public Object getT() {
    return null;
    }
    }

    public static class  B extends A {
    public String getT() {
    return null;
    }
    }
    }

    And after the compilation decompiled result class "B" will be following:
    public class SampleOne$B extends SampleOne$A {
    public SampleOne$B();

    public java.lang.String getT();
    Code:
    0:   aconst_null
    1:   areturn
    public java.lang.Object getT();
    Code:
    0:   aload_0
    1:   invokevirtual   #2// Call to Method getT:()Ljava/lang/String;
    4:   areturn
    }

    Above you can see there is new synthetic method "java.lang.Object getT()" which is not present in source code. That method acts as bridge method and all is does is delegating invocation to "java.lang.String getT()". Compiler has to do that, because in JVM method return type is part of method's signature, and creation of bridge method is the way to implement covariant return type.

    Now have a look at following example which is generics-specific:
    public class SampleTwo {
    public static class A<T> {
    public T getT(T args) {
    return args;
    }

    }


    public static class B extends A<String> {
    public String getT(String args) {
    return args;
    }

    }

    }

    after compilation class "B" will be transformed into following:
    public class SampleThree$B extends SampleThree$A{
    public SampleThree$B();

    public java.lang.String getT(java.lang.String);
    Code:
    0:   aload_1
    1:   areturn

    public java.lang.Object getT(java.lang.Object);
    Code:
    0:   aload_0
    1:   aload_1
    2:   checkcast       #2//class java/lang/String
    5:   invokevirtual   #3//Method getT:(Ljava/lang/String;)Ljava/lang/String;
    8:   areturn
    }

    here, the bridge method, which overrides method from base class "A", not just calling one with string argument (#3), but also performs type cast to "java.lang.String" (#2). It means, that if you will execute following code, ignoring compiler's "unchecked" warning, the result will be ClassCastException thrown from the bridge method:
    A a = new B();
    a.getT(
    new Object()));

    These two examples are the best known cases where bridge methods are used, but there is, at least, one more, where bridge method is used to "change" visibility of base class's methods. Have a look at following sample and try to guess where compiler may need the bridge method to be created:
    package samplefour;

    public class SampleFour {
    static class A {
    public void foo() {
    }

    }

    public static class C extends A {

    }

    public static class D extends A {
    public void foo() {
    }

    }

    }
    If you will decompile class C, you will see method "foo" there, which overrides method from base class and delegates to it:
    public class SampleFour$C extends SampleFour$A{

    public void foo();
    Code:
    0:   aload_0
    1:   invokespecial   #2//Method SampleFour$A.foo:()V
    4:   return

    }

    compiler needs that method, because class A is not public and can't be accessed outside it's package, but class C is public and all inherited method have to become visible outside the package as well. Note, that class D will not have bridge method, because it overrides "foo" and there is no need to "increase" visibility.
    It looks like, that type of bridge method, was introduced after bug which was fixed in Java 6. It means that before Java 6 that type of bridge method is not generated and method "C#foo" can't be called from package other than it's own via reflection, so following snippet causes IllegalAccessException, in cases when compiled on Java version < 1.6:
    package samplefive;

    SampleFour.C.
    class.getMethod("foo").invoke(new SampleFour.C());
    Normal invocation, without using reflection, will work fine.

    Probably there are some other cases where bridge methods are used, but there is no source of information about it. Also, there is no definition of bridge method, although you can guess it easily, it's pretty obvious from examples above, but still would be nice to have something in spec which states it clearly. In spite of the fact that method Method#isBridge() is part of public reflection API since Java1.5 and bridge flag is part of class file format, JVM and JLS specifications do not have any information what exactly is that and do not provide any rules when and how it should be used by compiler. All I could find is just reference in "Discussion" area here.
    posted @ 2011-08-20 10:19 happyenjoylife 閱讀(442) | 評論 (0)編輯 收藏

    導航

    <2011年8月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    統計

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: a毛片免费全部在线播放**| 疯狂做受xxxx高潮视频免费| 99re6免费视频| 亚洲AV成人片色在线观看| 一个人免费视频观看在线www| 亚洲午夜激情视频| 国产成年无码久久久免费| 久久青青草原亚洲AV无码麻豆| 日韩人妻一区二区三区免费| 久久综合亚洲鲁鲁五月天| 91在线视频免费91| 亚洲欧美日韩国产精品一区| 国产在线ts人妖免费视频| 免费国产高清毛不卡片基地| 国产国拍亚洲精品福利 | 免费人成视频在线观看网站| 亚洲一区免费观看| 成年在线观看网站免费| 亚洲成av人在线观看网站 | 国产一区二区三区免费视频| 人妻免费久久久久久久了| 亚洲av激情无码专区在线播放| 亚色九九九全国免费视频| 亚洲国产成人综合精品| 亚洲日本在线观看视频| 久久大香香蕉国产免费网站| 亚洲国产综合精品中文第一| 亚洲A∨午夜成人片精品网站| 免费网站看av片| 亚洲人成未满十八禁网站| 亚洲精品无码专区2| 久久精品人成免费| 美女扒开屁股让男人桶爽免费 | 亚洲成色WWW久久网站| 日韩精品福利片午夜免费观着| 免费国产va视频永久在线观看| 噜噜噜亚洲色成人网站∨| 亚洲精品国产自在久久 | 日韩人妻无码免费视频一区二区三区| 一级毛片a免费播放王色| 亚洲影视自拍揄拍愉拍|