2012-11-15 34 views
10

Giả sử tôi có loại truy vấnAndroid SQLite hiệu suất trong phức tạp truy vấn

String sql = "SELECT s.team_id, s.team_name, s.gp, s.w, s.t, s.l, s.go, s.ga, s.score, s.p FROM " 
      + "(SELECT team_id, team_name, SUM (gp) gp, SUM (w) w, SUM (t) t, SUM (l) l, SUM (GO) go, SUM (GA) ga, SUM (GO)- SUM (GA) score, SUM (2*w+t) p FROM " 
      + "(SELECT t._id team_id, t.name team_name, COUNT(CASE WHEN score_home IS NOT NULL THEN 1 END) gp, COUNT (CASE WHEN score_home > score_away THEN 1 END) w," 
      + " COUNT (CASE WHEN score_home = score_away THEN 1 END) t, COUNT (CASE WHEN score_home < score_away THEN 1 END) l," 
      + " SUM (score_home) go, SUM (score_away) ga" 
      + " FROM team_table t LEFT OUTER JOIN match_table m ON m.team_home = t._id" 
      + " WHERE t.tournament_id = ? GROUP BY t._id, t.name" 
      + " UNION ALL" 
      + " SELECT t._id team_id, t.name team_name, COUNT(CASE WHEN score_away IS NOT NULL THEN 1 END) gp, COUNT (CASE WHEN score_home < score_away THEN 1 END) w," 
      + " COUNT (CASE WHEN score_home = score_away THEN 1 END) t, COUNT (CASE WHEN score_home > score_away THEN 1 END) l," 
      + " SUM (score_away) go, SUM (score_home) ga" 
      + " FROM team_table t LEFT OUTER JOIN match_table m ON m.team_away = t._id" 
      + " WHERE t.tournament_id = ? GROUP BY t._id, t.name)" 
      + " GROUP BY team_id, team_name) s" 
      + " ORDER BY s.p DESC, s.score DESC, s.go ASC"; 

sau đó được sử dụng như thế này

Cursor cursor = database.rawQuery(sql, args); 

cursor.moveToFirst(); 
while (!cursor.isAfterLast()) { 
    TeamStats stat = new TeamStats(); 

    stat.setTeamId(cursor.getLong(0)); 
    stat.setTeamName(cursor.getString(1)); 
    stat.setGamesPlayed(cursor.getInt(2)); 
    stat.setWins(cursor.getInt(3)); 
    stat.setTies(cursor.getInt(4)); 
    stat.setLoses(cursor.getInt(5)); 
    stat.setGoalsOwn(cursor.getInt(6)); 
    stat.setGoalsAgaist(cursor.getInt(7)); 
    stat.setScore(cursor.getInt(8)); 
    stat.setPoints(cursor.getInt(9)); 

    stats.add(stat); 
    cursor.moveToNext(); 
} 
cursor.close(); 

Vì vậy, nó chọn các giá trị từ nhiều bảng, hiện một số hoạt động vv Như bạn có thể thấy truy vấn phức tạp khủng khiếp (rất khó gỡ lỗi) và hiệu suất dường như không tốt như tôi mong đợi. Câu hỏi của tôi là:

  1. Tôi có thể cải thiện hiệu suất bằng cách sử dụng một số loại câu lệnh đã chuẩn bị không?
  2. Sẽ nhanh hơn khi thực hiện các truy vấn đơn giản hơn và xử lý chúng một cách thủ công với một số mã tùy chỉnh?
+6

Cải thiện lược đồ cơ sở dữ liệu, khử chuẩn hóa, thêm chỉ mục và những thứ tương tự để truy vấn của bạn trở nên đơn giản và nhanh hơn. ['EXPLAIN QUERY PLAN'] (http://www.sqlite.org/eqp.html) là một cách tốt để xem sqlite nào với truy vấn của bạn – zapl

+1

trước tiên bạn nên xem xét định dạng truy vấn bằng cách nào đó có thể đọc được. stackoverflow không phải là nơi để cho thấy rằng bạn có thể tạo các câu lệnh sql obfuscated. – tkr

+1

@tkr À ... Đầu tiên, việc giảm giá cho việc từ chối các thay đổi của bạn là không đáng kể. Thứ hai, phần 'Chuỗi sql' là cần thiết vì mã sau sử dụng nó.Đó là lý do chính khiến tôi từ chối các thay đổi của bạn. Bạn không thể loại bỏ tất cả mã xung quanh và mong tôi chấp nhận nó. Tiếp theo thời gian, suy nghĩ về hành động của bạn và hành xử cho mình ... – user219882

Trả lời

6

Nếu tôi là bạn, tôi sẽ sao chép cơ sở dữ liệu sqlite của bạn để lưu trữ, sau đó thử thực hiện thủ công trong giao diện đồ họa SQLite trong khi thay thế các biến bị ràng buộc (?) với giá trị biến thực tế mà bạn có. Đối với GUI trên Windows, tôi thực sự thích SQLite Expert Personal và trên Linux sqliteman là khá tốt.

Khi gỡ lỗi SQL (trong dòng lệnh hoặc GUI), hãy đảm bảo phân tích các câu lệnh SQL của bạn bằng cách chạy chúng dưới EXPLAIN và/hoặc EXPLAIN QUERY PLAN. Xem ra để quét bảng. Bạn nên cố gắng loại bỏ các bản quét đắt tiền bằng cách thêm các chỉ mục. Nhưng đừng lập chỉ mục mọi thứ - điều đó có thể làm mọi thứ tồi tệ hơn. Thông thường, bạn có thể đạt được hiệu suất lớn bằng cách sử dụng các chỉ mục phức hợp (nhiều cột). Lưu ý rằng, trên bất kỳ bảng SQLite nào, không thể sử dụng nhiều hơn chỉ một chỉ mục (trong khi chạy câu lệnh SQL đã cho) - vì vậy, hãy chọn các chỉ mục của bạn một cách khôn ngoan. (Xem thêm phần giải thích cơ bản trong Query Planning.)

Và để giải quyết mối quan tâm của bạn về xử lý dữ liệu trong Java vs SQLite - Tôi nghĩ rằng hoàn toàn tối ưu hóa (với chỉ số thích hợp, vv) SQLite truy vấn chống lại dữ liệu quan hệ sẽ (hầu như luôn luôn sẽ nhanh hơn xử lý thủ công dữ liệu này trong Java. Điều này phải đặc biệt đúng trong trường hợp của bạn - tất cả dữ liệu của bạn về cơ bản là quan hệ.

Một lưu ý nhỏ mặc dù: APK Android của bạn bằng Java có thể có nhiều bộ nhớ hơn SQLite theo mặc định - bạn có thể muốn tăng kích thước bộ nhớ cache SQLite cho cơ sở dữ liệu của mình bằng cách sử dụng setMaxSqlCacheSize() (tương đương PRAGMA cache_size). Mặc định của Android là 10 (tối đa 100), hãy thử tăng nó và xem có tạo sự khác biệt nào cho truy vấn của bạn hay không. Lưu ý rằng SQLite desktop mặc định cho thiết lập này là cao hơn nhiều - 2000.

0

Không chính xác câu trả lời về truy vấn nhanh, nhưng: Bạn có thể thử Sử dụng bảng trợ giúp bổ sung và điền chúng bằng cách xác định trình kích hoạt trên bảng dữ liệu thực. Bằng cách này, bạn sẽ có hầu hết dữ liệu tổng hợp sẵn sàng trong tầm tay và các truy vấn sẽ đơn giản hơn.

1

Cá nhân tôi khuyên bạn nên duy trì các truy vấn và cấu trúc cơ sở dữ liệu của mình đơn giản nhất có thể trên Android và thực hiện xử lý chính thông qua mã.

Một lý do, vì cấu trúc cơ sở dữ liệu phức tạp trộn lẫn với nhu cầu xử lý nâng cấp và hạ cấp của các phiên bản khác nhau của ứng dụng mà không làm mất dữ liệu, có thể nhanh chóng thoát ra khỏi tầm tay. Bây giờ tôi có xu hướng thiết lập và xử lý dữ liệu theo kiểu NoSQL.

Lý do khác là do SQLite thiếu nhiều chức năng cần thiết trong các tác vụ thực tế và bạn sẽ kết thúc xử lý dữ liệu thông qua mã. Ví dụ không có chức năng trang điểm để tìm kiếm các mục gần nhất, có thể đã phức tạp;)

private String getRelitiveDistanceQuery(double lng, double lat, int max){ 
    return "SELECT *, " + 
    // NOTE: this long query was done because there are no trig functions in SQLite so this is an series expansion of some of the functions 
    "((3.14159265358979/2-(((("+Double.toString(lat)+"*0.0174532925199433)-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/6+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/120-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/5040)*((`lat`*0.0174532925199433)-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/6+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/120-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/5040)+(1-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/2+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/24-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/720)*(1-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/2+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/24-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/720)*(1-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/2+(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/24-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/720))+1/6*((("+Double.toString(lat)+"*0.0174532925199433)-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/6+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/120-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/5040)*((`lat`*0.0174532925199433)-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/6+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/120-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/5040)+(1-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/2+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/24-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/720)*(1-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/2+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/24-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/720)*(1-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/2+(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/24-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/720))*((("+Double.toString(lat)+"*0.0174532925199433)-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/6+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/120-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/5040)*((`lat`*0.0174532925199433)-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/6+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/120-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/5040)+(1-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/2+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/24-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/720)*(1-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/2+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/24-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/720)*(1-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/2+(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/24-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/720))*((("+Double.toString(lat)+"*0.0174532925199433)-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/6+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/120-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/5040)*((`lat`*0.0174532925199433)-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/6+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/120-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/5040)+(1-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/2+("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/24-("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)*("+Double.toString(lat)+"*0.0174532925199433)/720)*(1-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/2+(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/24-(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)*(`lat`*0.0174532925199433)/720)*(1-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/2+(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/24-(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)*(("+Double.toString(lng)+" -`lng`)*0.0174532925199433)/720))))) AS relDistance " + 
    "FROM `"+TABLE_ITEMS+"` ORDER BY relDistance ASC LIMIT "+Integer.toString(max); 
} 

Tôi đã viết một kịch bản perl để tạo ra mã này, nó mở rộng các chức năng trang điểm, và nó thực sự hoạt động khá tốt, nhưng nó là không thể quản lý và tôi sẽ không giới thiệu nó.

2

Trước tiên, tôi không biết nhiều về SQLite nhưng tôi cho rằng nó sẽ hoạt động nhiều hơn hoặc ít hơn như MS SQL-Server.

Thông thường, một vấn đề hiệu suất cho một truy vấn đơn giản như thế này thường liên quan đến trường hợp chỉ mục bị thiếu dẫn đến quét toàn bộ bảng thay vì quét bảng một phần hoặc tìm kiếm bảng. Nếu bạn không có chỉ mục trên team_table.tournament_id thì SQLite sẽ phải quét toàn bộ bảng để thực hiện "t.tournament_id =?" hoạt động. Điều tương tự sẽ xảy ra với match_table.team_home và match_table.team_away: một chỉ mục bị thiếu sẽ dẫn đến việc quét toàn bộ bảng cho các hoạt động nối trên m.team_home và m.team_away sẽ được thực hiện.

Đối với phần còn lại, bạn có thể đơn giản hóa truy vấn của mình theo hai cách. Việc đầu tiên sẽ là bỏ truy vấn phụ bên ngoài và sử dụng các biểu thức hoặc các cột sắp xếp theo thứ tự của bạn; ví dụ: bạn có thể thay thế "ORDER BY sp DESC, s.score DESC, s.go ASC" bằng "ORDER BY SUM (2 * w + t) DESC, SUM (GO) - SUM (GA) DESC, SUM (GO) ASC "và loại bỏ các truy vấn phụ.

Cách thứ hai sẽ được thay thế UNION với một truy vấn bằng cách thực hiện bên trái tham gia hoạt động trên cả hai m.team_home và m.team_away cùng một lúc:

... TỪ team_table t LEFT OUTER JOIN match_table m ON (m.team_home = t._id hoặc m.team_away = t._id) ...

Sau đó, rất dễ thay đổi báo cáo Trường hợp của bạn để tính toán đúng các điểm số khác nhau trên t._id bằng m.team_home hoặc m.team_away. Bằng cách này, không chỉ bạn có thể bỏ UNION mà còn có thể loại bỏ truy vấn phụ thứ hai.

Cuối cùng, bạn phải xem xét việc sử dụng phép nối trái; vì tôi không chắc liệu nó có thực sự cần thiết trong việc sử dụng Inner Join thông thường hay không.

Sau đó, bạn sẽ kết thúc với một truy vấn tham gia đơn giản với một nhóm theo và một đơn đặt hàng theo và không có truy vấn con hoặc công đoàn và có thể không có tham gia trái nào. Tuy nhiên, vào thời điểm này, các biểu thức trong Order By có thể trở nên phức tạp một chút vì vậy bạn sẽ phải đưa ra quyết định giữ chúng theo cách này, đặt lại truy vấn phụ hoặc sử dụng thứ tự cột (lựa chọn ưa thích cuối cùng của tôi).

Nếu không có Liên minh, truy vấn sẽ thực hiện ít nhất hai lần nhanh nhưng cuối cùng, để có hiệu suất tốt, yêu cầu cuối cùng sẽ là có tất cả các chỉ mục phù hợp; nếu không, hiệu suất sẽ không bao giờ tốt nếu máy chủ sql cần thực hiện nhiều bản quét bảng đầy đủ.

0

nếu bạn đang sử dụng tuyên bố chuẩn bị sau đó nó có lợi cho bạn vì 1. tuyên bố chuẩn bị là an toàn hơn nhiều tiêm 2. sql khó 3. chúng không quá phức tạp 4. bảo trì dễ dàng

+0

Tôi biết tất cả điều đó nhưng tôi đã tự hỏi nếu có một điều _PreparedStatement_ trong Android trả về một 'Con trỏ' – user219882

Các vấn đề liên quan