Thứ Bảy, 10 tháng 12, 2016

25 típ để tăng hiệu suất cho câu lệnh sql

Mỗi khách hàng hay người dùng đều muốn được trả về dữ liệu nhanh nhất do đó chúng ta cần thiết kế một cơ sở dữ liệu tốt mà tăng hiệu suất cho mỗi lẫn thao tao với dữ liệu. Không có con đường thẳng để định nghĩa hiệu suất tốt nhất nhưng có nhiều cách để cải thiện câu lệnh sql ví dụ như tạo index , sử dụng join , viết lại subquery để chỉ dùng join v.v.
Là Dev, chúng ta biết sql có thể viết bằngrất nhiều cách nhưng chúng ta nên follow theo cách tốt nhất để đạt được hiệu suất tốt nhất. Dưới đây là các típ cho chúng ta:
  1. Hãy dùng EXISTS thay vì IN để kiểm tra sự tồn tại của dữ liệu.
  2. Tránh * trong câu lệnh SELECT. Hãy dùng tên cột thích hợp.
  3. Chọn loại dữ liệu thích hợp . Ví dụ lưu chuỗi sử dụng loại varchar thay vì sử dụng loại Text. Khi muốn sử dụng loại Text, là khi bạn cần lưu dữ liệu lơn (nhiều hơn 8000 ký tự).
  4. Tránh dùng nchar và nvarchar vì cả hai đều tăng bộ nhớ lên gấp đôi so với char và varchar.
  5. Tránh NULL đối với những trường mà đã cố định độ dài. Trong trường hợp yêu cầu là NULL hãy sử dụng một trường loại varchar với độ dài tùy biến thì vẫn lấy space ít hơn là NULL.
  6. Tránh dùng mệnh đề Having. Chỉ dùng khi muốn lọc kết quả trả về.
  7. Hãy tạo ra indexs là cách tốt nhất tăng tốc . Indexs bao gồm Clustered và Non-Clustered.
  8. Hãy giữ index của clustered nhỏ thôi vì trường mà dùng trong cluster index đó thì cũng được dùng trong non-clustered index.
  9. Đa số cột được chọn nên đặt trong non-clustered index.
  10. Những index nào không được dùng thì nên xóa đi.
  11. Tốt hơn là tạo ra index trên những cột có giả trị là số thay vì là ký tự. Giá trị số sử dụng ít bộ nhớ hơn ký tự.
  12. Dùng câu lệnh join thay vì dùng select trong select
  13. Hãy sử dụng mệnh đề WHERE để giới hạn cỡ của bảng kết quả trả về mà được tạo ra với câu lệnh join.
  14. Hãy dùng TABLOCKX trong khi chèn dữ liệu vào bảng và TABLOCK trong khi merging dữ liệu
  15. Sử dụng WITH (NOLOCK) trong khi truy xuất dữ liệu từ bất kỳ một bảng nào.
  16. Dùng SET NOCOUNT ON và sử dụng TRY – CATCH để tránh điều kiện deadlock.
  17. Tránh dùng cursor vì nó ảnh hưởng đến hiệu suất của chương trình rất chậm.
  18. Sử dụng biến TABLE thay vì dùng bảng TEMP. Dùng bảng TEMP đòi hỏi tương tác với cơ sở dữ liệu TEMPDB mà mất thời gian để thực hiện một tác vụ.
  19. Sử dụng UNION ALL thay vì UNION nếu có thể.
  20. Sử dụng tên Schema trước tên đối tượng SQL.
  21. Sử dụng Stored Procedure cho những dữ liệu thường xuyên được sử dụng và những query hỗn hợp , hoặc những câu lệnh chứa nhiều logic phức tạp.
  22. Giữ transaction nhỏ nhất có thể vì transaction khóa việc xử lý dữ liệu bảng và có thể dẫn đến kết quả bị deadlocks.
  23. Tránh tiền tố “sp_” với tên store procedure người dùng tự định nghĩa bởi vì SQL server đầu tiên tìm kiếm những thủ tục người dùng định nghĩa trong cơ sở dử liệu master và sau đó mới sử dụng phiên làm việc của cơ sở dữ liệu hiện hành.
  24. Tránh dùng câu query Non-correlated . Sử dụng câu query này như một câu query riêng instead thay vì là query chính và lưu output trong một biến, mà có thể tham chiếu đến câu query chính hoặc là một phần sau của batch.
  25. Tránh Table Valued Functions (TVFs) với nhiều câu lệnh. Vì nó giảm hiệu suất
Xem thêm : https://www.codeproject.com/articles/34372/top-steps-to-optimize-data-access-in-sql-server

Thứ Sáu, 14 tháng 10, 2016

[Android] Navigation Drawer

   Navigation Drawer là một bảng điều khiển nằm ở cạnh bên trái màn hình,nó hiển thị sự tùy chọn điều hướng của main app.
   Nó được ẩn đi trong gần như hầu hết thời gian,và được gọi khi người dùng lướt ngón tay từ bên cạnh trái màn hình vào hoặc khi người dùng ấn vào biểu tượng ứng dụng trên thanh action bar.

   Bài viết sẽ mô tả làm như thế nào để triển khai một navigation drawer sử dụng 'DrawerLayout APIs' có trong thư viện hỗ trợ 'Support Library'

   Một số lưu ý về nguyên tắc thiết kế,khuôn mẫu của Navigation Drawer:
 https://material.google.com/patterns/navigation-drawer.html#navigation-drawer-specs


  1. Tạo một Drawer Layout
    • Để thêm một navigation drawer,khai báo tại giao diện người dùng một đối tượng DrawerLayout như một root view trong file layout .xml . 
    • Ở trong DrawerLayout,thêm một view mà chứa cái nội dung chính cho màn hình (Màn hình để hiển thị khi mà Navigation Drawer ẩn đi) và một view khác chứa nội dung của chính cái navigation drawer đấy.
    • Thường sử dụng FrameLayout cho màn hình chính với vai trò là một Fragment trong khi app chạy để có thể dễ dàng thay đổi,di chuyển giữa các màn hình. Và một ListView để hiển thị nội dung cho Navigation Drawer.
    • <android.support.v4.widget.DrawerLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/drawer_layout"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
          <!-- The main content view -->
          <FrameLayout
              android:id="@+id/content_frame"
              android:layout_width="match_parent"
              android:layout_height="match_parent" />
          <!-- The navigation drawer -->
          <ListView android:id="@+id/left_drawer"
              android:layout_width="240dp"
              android:layout_height="match_parent"
              android:layout_gravity="start"
              android:choiceMode="singleChoice"
              android:divider="@android:color/transparent"
              android:dividerHeight="0dp"
              android:background="#111"/>
      </android.support.v4.widget.DrawerLayout>
    • Dựa vào code ở trên chúng ta có thể rút ra được một số điều quan trọng như:
    1. Main content view phải được khai báo như là phần tử đầu tiên của root view vì XML order được triển khai theo z-ordering,nghĩa là phần tử khai báo trước sẽ nằm ở phía sau.
    2. Main content view được đặt giá trị là match_parent vì nó đại diện cho toàn bộ UI khi drawer ẩn đi
    3. Drawer view (List view) phải được xác định trọng lực ngang của nó với thuộc tính : android:layout_gravity. Để hỗ trợ ngôn ngữ đọc từ trái sang phải,giá trị của thuộc tính này phải được đặt là 'start' thay vì 'left' cho bố cục hỗ trợ đọc từ phải sang trái.
    4. Drawer view được xác định chiều rộng với giá trị dp. Giá trị này không nên vượt quá 320 dp để người dùng có thể nhìn thấy một phần của main content phía sau. Thường được đặt là 240dp
  2. Khởi tạo Drawer List
    • Trong activity,một trong những điều đầu tiên cần phải khởi tạo là list item của navigation drawer. List item này phụ thuộc vào nội dung app bạn là gì. Và nó được khởi tạo cũng như đổ dữ liệu y hệt như list view bình thường. Sử dụng Adapter (Như là ArrayAdapter hoặc là SimpleCursorAdapter)
    • Dưới đây là một ví dụ khởi tạo list navigation với String Array:
      public class MainActivity extends Activity {
          private String[] mPlanetTitles;
          private DrawerLayout mDrawerLayout;
          private ListView mDrawerList;
          ...
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              mPlanetTitles = getResources().getStringArray(R.array.planets_array);
              mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
              mDrawerList = (ListView) findViewById(R.id.left_drawer);
      
              // Set the adapter for the list view
              mDrawerList.setAdapter(new ArrayAdapter<String>(this,
                      R.layout.drawer_list_item, mPlanetTitles));
              // Set the list's click listener
              mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
      
              ...
          }
      }
    •  Đoạn code có phương thức setOnItemClickListener() để nhận được sự kiện click vào drawer list. Phần tiếp theo sẽ cho bạn thấy làm thế nào để triển khai giao diện và thay đổi content view khi người dùng chọn một item.
  3. Xử lý sự kiện click điều hướng
    • Khi người dùng chọn một item trong drawer list,hệ thống gọi phương thức onItemClick() trong lớp OnItemClickListener được gán trong phương thức setOnItemClickListener(OnItemClickListener listener).
    • Trong ví dụ dưới đây,mỗi khi người dùng lựa chọn một item trong list,main content view sẽ hiển thị những fragment khác nhau:
      private class DrawerItemClickListener implements ListView.OnItemClickListener {
          @Override
          public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
              selectItem(position);
          }
      }
      /** Swaps fragments in the main content view */
      private void selectItem(int position) {
          // Create a new fragment and specify the planet to show based on position
          Fragment fragment = new PlanetFragment();
          Bundle args = new Bundle();
          args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
          fragment.setArguments(args);
      
          // Insert the fragment by replacing any existing fragment
          FragmentManager fragmentManager = getFragmentManager();
          fragmentManager.beginTransaction()
                         .replace(R.id.content_frame, fragment)
                         .commit();
      
          // Highlight the selected item, update the title, and close the drawer
          mDrawerList.setItemChecked(position, true);
          setTitle(mPlanetTitles[position]);
          mDrawerLayout.closeDrawer(mDrawerList);
      }
      @Override
      public void setTitle(CharSequence title) {
          mTitle = title;
          getActionBar().setTitle(mTitle);
      }
  4. Lắng nghe sự kiện đóng hoặc mở
    • Để lắng nghe sự kiện đóng hoặc mở navigation drawer,gọi phương thức setDrawerListener() của đối tượng DrawerLayout và gán cho nó một thực thi của lớp DrawerLayout.DrawerListener. Giao diện này sẽ cung cấp một hàm callbacks cho 2 sự kiện của drawer là 2 phương thức onDrawerOpened() và onDrawerClosed(). 
    • Tuy nhiên,xa hơn việc thực thi lớp DrawerListener,nếu app của bạn có actionbar,bạn có thể thay thế bằng cách kế thừa lớp ActionBarDrawerToggle. Lớp này là là lớp phụ thuộc của DrawerListener nên bạn vẫn có thể override lại những callback trên,và còn có thể thực thi những hành vi tương tác giữa biểu tượng trên thanh actionbar và navigation drawer (Sẽ được trình bày sâu hơn vào phần tiếp theo)
    • Như những gì đã trình bày ở bài hướng dẫn thiết kế Navigation Drawer,bạn nên tùy chỉnh nội dung của action bar khi drawer hiển thị. Vì vậy chúng ta sẽ thay đổi tên title action bar và xóa action items mà liên kết với main content đang hiển thi. Phần code dưới đây sẽ hướng dẫn bạn làm việc đó như thế nào với việc override lại các phương thức của lớp DrawerListener với một instance (thực thể) của lớp ActionbarDrawerToggle:
      public class MainActivity extends Activity {
          private DrawerLayout mDrawerLayout;
          private ActionBarDrawerToggle mDrawerToggle;
          private CharSequence mDrawerTitle;
          private CharSequence mTitle;
          ...
      
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              ...
      
              mTitle = mDrawerTitle = getTitle();
              mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
              mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
                      R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
      
                  /** Called when a drawer has settled in a completely closed state. */
                  public void onDrawerClosed(View view) {
                      super.onDrawerClosed(view);
                      getActionBar().setTitle(mTitle);
                      invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                  }
      
                  /** Called when a drawer has settled in a completely open state. */
                  public void onDrawerOpened(View drawerView) {
                      super.onDrawerOpened(drawerView);
                      getActionBar().setTitle(mDrawerTitle);
                      invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
                  }
              };
      
              // Set the drawer toggle as the DrawerListener
              mDrawerLayout.setDrawerListener(mDrawerToggle);
          }
      
          /* Called whenever we call invalidateOptionsMenu() */
          @Override
          public boolean onPrepareOptionsMenu(Menu menu) {
              // If the nav drawer is open, hide action items related to the content view
              boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
              menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
              return super.onPrepareOptionsMenu(menu);
          }
      }
  5. Đóng hoặc mở với app icon
    • Phần này sẽ mô tả tham số khởi tạo của lớp ActionBarDrawerToggle và những bước cần thiết để cài đặt nhằm xử lý những tương tác giữa icon của action bar và Navigation Drawer
    • Người dùng có thể mở và đóng navigation drawer với thao tác lướt nhưng nếu app của bạn sử dụng action bar,bạn nên cho phép người dùng mở và đóng navigation bar bằng cách chạm vào biểu tượng trên thanh action bar. Và biểu tượng app này cũng nên biểu thị sự hiện diện của navigation drawer với biểu tượng đặc biệt (3 dấu * dọc nhau). Bạn có thể thực hiện tất cả các hành vi này bằng việc sử dụng ActionBarDrawerToggle mà đã được giới thiệu ở phần trước.
    • Để có thể sử dụng được ActionBarDrawerToggle,bạn cần tạo một instance của nó với hàm khởi tạo cùng với những tham số cần thiết sau
      • Activity chủ của drawer
      • DrawerLayout (tất nhiên)
      • Drawable resource để sử dụng làm icon đại diện cho drawer
      • 1 chuỗi String để mô tả cho hành động 'open drawer'
      • 1 chuỗi String để mô tả cho hành động 'close drawer'
    • Bây giờ thì có hoặc không bạn tạo một subclass của ACtionBarDrawerToggle như một listener cho drawer của bạn,bạn cần gọi ActionBarDrawerToggle trong một vài chỗ xuyên suốt vòng đời activity của bạn
      public class MainActivity extends Activity {
          private DrawerLayout mDrawerLayout;
          private ActionBarDrawerToggle mDrawerToggle;
          ...
      
          public void onCreate(Bundle savedInstanceState) {
              ...
      
              mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
              mDrawerToggle = new ActionBarDrawerToggle(
                      this,                  /* host Activity */
                      mDrawerLayout,         /* DrawerLayout object */
                      R.drawable.ic_drawer,  /* nav drawer icon to replace 'Up' caret */
                      R.string.drawer_open,  /* "open drawer" description */
                      R.string.drawer_close  /* "close drawer" description */
                      ) {
      
                  /** Called when a drawer has settled in a completely closed state. */
                  public void onDrawerClosed(View view) {
                      super.onDrawerClosed(view);
                      getActionBar().setTitle(mTitle);
                  }
      
                  /** Called when a drawer has settled in a completely open state. */
                  public void onDrawerOpened(View drawerView) {
                      super.onDrawerOpened(drawerView);
                      getActionBar().setTitle(mDrawerTitle);
                  }
              };
      
              // Set the drawer toggle as the DrawerListener
              mDrawerLayout.setDrawerListener(mDrawerToggle);
      
              getActionBar().setDisplayHomeAsUpEnabled(true);
              getActionBar().setHomeButtonEnabled(true);
          }
      
          @Override
          protected void onPostCreate(Bundle savedInstanceState) {
              super.onPostCreate(savedInstanceState);
              // Sync the toggle state after onRestoreInstanceState has occurred.
              mDrawerToggle.syncState();
          }
      
          @Override
          public void onConfigurationChanged(Configuration newConfig) {
              super.onConfigurationChanged(newConfig);
              mDrawerToggle.onConfigurationChanged(newConfig);
          }
      
          @Override
          public boolean onOptionsItemSelected(MenuItem item) {
              // Pass the event to ActionBarDrawerToggle, if it returns
              // true, then it has handled the app icon touch event
              if (mDrawerToggle.onOptionsItemSelected(item)) {
                return true;
              }
              // Handle your other action bar items...
      
              return super.onOptionsItemSelected(item);
          }
      
          ...
      }

Thứ Tư, 27 tháng 1, 2016

Lưu ý khi học Java

Con người là 1 lớp: chân, tay, tuổi, học vấn,... là thuộc tính, đi chạy, nhảy là phương thức.
Di chuyển là một interface: chỉ bao gồm phương thức..

Đến đây chắc bạn hiểu rồi.
Một lớp có thể thừa kế (extends) một lớp khác: con người extends động_vật
một interface có thể extends từ một interface: di_chuyển extends cử_động.
một lớp có thể implement (triển khai) một interface: con_người implements di_chuyển

Thứ Tư, 6 tháng 1, 2016

Kinh nghiệm xương máu của anh chị đi trước

[01/06/2015]
Appending model là một mô hình thiết kế CSDL tối ưu cho việc ghi, khi chỉ insert mà không có update, delete. Đây là một mô hình rất tốt cho các CSDL đòi hỏi hiệu năng rất cao việc ghi. 

Nó có thể mở rộng ra không chỉ cho các table trong database, mà còn với các cấu trúc file. Đây cũng là mô hình được các hệ thống như viễn thông, hệ thống quảng cáo sử dụng để xây dựng các cấu trúc lưu trữ đòi hỏi hiệu năng rất cao.