<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免费观看| 四虎国产精品免费永久在线| 国产AV无码专区亚洲精品| 亚洲av鲁丝一区二区三区| 国产精品高清免费网站| 蜜臀AV免费一区二区三区| 久久久久亚洲AV无码永不| 国产精成人品日日拍夜夜免费| 国产av天堂亚洲国产av天堂 | 18禁美女裸体免费网站| 亚洲毛片基地日韩毛片基地| 国产高清视频免费在线观看| 亚洲精品国产成人影院| 最近免费字幕中文大全| 久久精品国产亚洲av麻豆小说| 57pao国产成永久免费视频| 亚洲国产精品综合福利专区| WWW免费视频在线观看播放| 亚洲乱码一区二区三区在线观看 | 四虎精品成人免费视频| 亚洲日韩人妻第一页| 国产精品高清视亚洲一区二区| 免费电影在线观看网站| 美女被暴羞羞免费视频| 成人毛片免费观看视频在线| 午夜亚洲WWW湿好爽| 国产午夜亚洲精品理论片不卡 | 久久精品亚洲一区二区| 免费专区丝袜脚调教视频| 亚洲老熟女五十路老熟女bbw| 亚洲国产成人精品女人久久久 | 久99久精品免费视频热77| 亚洲综合丁香婷婷六月香| 最近免费mv在线电影| 亚洲人成人伊人成综合网无码| 免费在线不卡视频| 亚洲AV无码AV男人的天堂不卡| 中文字幕亚洲不卡在线亚瑟| 亚洲一区免费视频| 一区二区在线视频免费观看| 亚洲麻豆精品果冻传媒|