Có thể chèn nhiều hàng cùng một lúc trong cơ sở dữ liệu SQLite không?


551

Trong MySQL, bạn có thể chèn nhiều hàng như thế này:

INSERT INTO 'tablename' ('column1', 'column2') VALUES
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2'),
    ('data1', 'data2');

Tuy nhiên, tôi đang gặp lỗi khi tôi cố gắng làm một cái gì đó như thế này. Có thể chèn nhiều hàng cùng một lúc trong cơ sở dữ liệu SQLite không? Cú pháp để làm điều đó là gì?


26
Không phải là một bản sao, vì câu hỏi này đang hỏi về SQLite một cách cụ thể, trái ngược với SQL nói chung (mặc dù một số câu trả lời cho câu hỏi đó rất hữu ích cho câu hỏi này).
Brian Campbell

5
Trên các phần chèn số lượng lớn: stackoverflow.com/questions/1711631/ trên
tuinstoel

5
Câu hỏi là tại sao bạn nên làm điều đó. Vì SQlite đang được xử lý trên cùng một máy và bạn có thể gói nhiều lần chèn vào một giao dịch mà tôi không thấy sự cần thiết?
andig

2
Có, Bắt đầu từ phiên bản 2012-03-20 (3.7.11), cú pháp của bạn được hỗ trợ.
mjb

Câu trả lời:


607

cập nhật

Như BrianCampbell chỉ ra ở đây , SQLite 3.7.11 trở lên hiện hỗ trợ cú pháp đơn giản hơn của bài viết gốc . Tuy nhiên, cách tiếp cận được hiển thị vẫn phù hợp nếu bạn muốn tương thích tối đa trên các cơ sở dữ liệu cũ.

câu trả lời gốc

Nếu tôi có đặc quyền, tôi sẽ trả lời câu trả lời của sông : Bạn có thể chèn nhiều hàng trong SQLite, bạn chỉ cần cú pháp khác nhau . Để làm cho nó hoàn toàn rõ ràng, ví dụ về OP OPs:

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2'),
  ('data1', 'data2');

Điều này có thể được đúc lại thành SQLite như:

     INSERT INTO 'tablename'
          SELECT 'data1' AS 'column1', 'data2' AS 'column2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'
UNION ALL SELECT 'data1', 'data2'

một lưu ý về hiệu suất

Ban đầu tôi đã sử dụng kỹ thuật này để tải các bộ dữ liệu lớn từ Ruby on Rails một cách hiệu quả. Tuy nhiên , như Jaime Cook chỉ ra , không rõ đây là bất kỳ cá nhân nào nhanh hơn INSERTstrong một giao dịch:

BEGIN TRANSACTION;
INSERT INTO 'tablename' table VALUES ('data1', 'data2');
INSERT INTO 'tablename' table VALUES ('data3', 'data4');
...
COMMIT;

Nếu hiệu quả là mục tiêu của bạn, bạn nên thử điều này trước.

một lưu ý về UNION vs UNION ALL

Như nhiều người đã nhận xét, nếu bạn sử dụng UNION ALL(như được hiển thị ở trên), tất cả các hàng sẽ được chèn, vì vậy trong trường hợp này, bạn sẽ nhận được bốn hàng data1, data2. Nếu bạn bỏ qua ALL, thì các hàng trùng lặp sẽ bị loại bỏ (và hoạt động có lẽ sẽ chậm hơn một chút). Chúng tôi đang sử dụng UNION ALL vì nó phù hợp hơn với ngữ nghĩa của bài viết gốc.

kết thúc

PS: Vui lòng +1 câu trả lời của sông , vì nó đã trình bày giải pháp trước.


102
Một lưu ý nữa, sqlite dường như chỉ hỗ trợ tối đa 500 liên kết như vậy chọn cho mỗi truy vấn, vì vậy nếu bạn đang cố gắng gửi nhiều dữ liệu hơn, bạn sẽ cần chia nó thành 500 khối phần tử ( sqlite.org/limits.html )
Jamie Cook

3
Đồng ý: SQLite không phải là nút cổ chai, đó là chi phí chung của các giao dịch ORM riêng lẻ (trong trường hợp của tôi, Ruby On Rails). Vì vậy, nó vẫn là một chiến thắng lớn.
sợ hãi_fool

3
Làm thế nào để giải pháp này hoặc giải pháp 3.7.11 so với việc sử dụng các khối giao dịch? nó nhanh hơn insert into t values (data),(data),(data)hay begin transaction; insert into t values (data);insert into t values (data);insert into t values (data);Commit;?
Dan

5
Một lưu ý nữa: hãy cẩn thận! cú pháp này loại bỏ các hàng trùng lặp! sử dụng UNION ALLđể tránh điều đó (hoặc cho một số tăng hiệu suất nhỏ).
chacham15

1
@Shadowfax để kiểm tra phiên bản SQLite, xem xét sqlite3.sqlite_version(nó phải là 3.7.x hoặc 3.8.x), chứ không phải sqlite3.version(đó chỉ là phiên bản của mô-đun python).
tối đa

562

Có, điều đó là có thể, nhưng không phải với các giá trị chèn được phân tách bằng dấu phẩy thông thường.

Thử cái này...

insert into myTable (col1,col2) 
     select aValue as col1,anotherValue as col2 
     union select moreValue,evenMoreValue 
     union...

Đúng, nó hơi xấu nhưng đủ dễ để tự động hóa việc tạo ra câu lệnh từ một tập hợp các giá trị. Ngoài ra, có vẻ như bạn chỉ cần khai báo tên cột trong lần chọn đầu tiên.


36
Vui lòng sử dụng UNION ALLkhông UNION. Ngoại trừ nếu bạn muốn loại bỏ trùng lặp.
Benoit

4
Nếu bạn muốn ID tự động tăng, hãy cung cấp cho chúng giá trị NULL.
lenooh

241

Có, kể từ SQLite 3.7.11, điều này được hỗ trợ trong SQLite. Từ tài liệu SQLite :

Cú pháp câu lệnh SQLite INSERT

(khi câu trả lời này ban đầu được viết, điều này không được hỗ trợ)

Đối với khả năng tương thích với các phiên bản cũ của SQLite, bạn có thể sử dụng các thủ thuật được đề xuất bởi andyfearless_fool sử dụng UNION, nhưng đối với 3.7.11 và sau đó là cú pháp đơn giản được mô tả ở đây nên được ưa thích.


3
Tôi muốn nói rằng sơ đồ cho phép nhiều hàng, vì có một vòng khép kín với dấu phẩy bên ngoài dấu ngoặc đơn sau VALUES.
Julian Gerer

@JohannesGerer Họ đã cập nhật hình ảnh này kể từ khi tôi nhúng nó. Bạn có thể xem sơ đồ tại thời điểm tôi nhúng nó vào Lưu trữ Internet . Trên thực tế, chỉ hai tháng trước , họ đã thêm hỗ trợ cho nhiều hàng trong một lần chèn và chỉ hai ngày trước họ đã phát hành một phiên bản với sự thay đổi đó. Tôi sẽ cập nhật câu trả lời của tôi cho phù hợp.
Brian Campbell

1
@Brian, bạn có thể vui lòng trích dẫn văn bản tài liệu SQLite, nói rằng điều này có thể? Tôi đọc lại tài liệu chèn 3 lần và không tìm thấy gì về việc chèn nhiều hàng, nhưng chỉ có hình này (và không có gì về dấu phẩy VALUES (...), (...)) :(
Prizoff

1
@Prizoff Tôi đã liên kết với cam kết trong đó hỗ trợ này đã được thêm vào , bao gồm cả các trường hợp thử nghiệm. Bạn có thể thấy trong sơ đồ (so sánh liên kết IA ), rằng có một vòng lặp xung quanh biểu thức sau VALUES, chỉ ra rằng nó có thể được lặp lại cách nhau bởi dấu phẩy. Và tôi đã liên kết với các ghi chú phát hành cho phiên bản thêm tính năng, trong đó nêu rõ "Tăng cường cú pháp INSERT để cho phép nhiều hàng được chèn thông qua mệnh đề VALUES."
Brian Campbell

1
@Prizoff tôi đã đề cập này cho nhà duy trì SQLite, ông đã cam kết một sửa chữa đó là có sẵn trong bản dự thảo tài liệu hướng dẫn . Tôi đoán nó sẽ có trong tài liệu chính thức kể từ lần phát hành tiếp theo.
Brian Campbell

57

Tôi đã viết một số mã ruby ​​để tạo ra một phần tử chèn nhiều hàng 500 phần tử từ một loạt các câu lệnh chèn nhanh hơn đáng kể so với việc chạy các phần chèn riêng lẻ. Sau đó, tôi đã thử chỉ đơn giản là gói nhiều lần chèn vào một giao dịch và thấy rằng tôi có thể tăng tốc cùng loại với mã ít hơn đáng kể.

BEGIN TRANSACTION;
INSERT INTO table VALUES (1,1,1,1);
INSERT INTO table VALUES (2,2,2,2);
...
COMMIT;

1
nhưng điều này không hoạt động trong mã, trong khi nó đang làm việc trực tiếp trong trình quản lý SQLite. Trong mã, nó chỉ chèn hàng thứ 1 :(
Vaibhav Saran

4
Tôi đang sử dụng kiểu chèn mã này và nó hoạt động hoàn hảo. Bạn chỉ phải đảm bảo rằng bạn gửi TẤT CẢ SQL cùng một lúc. Đây là một sự gia tăng tốc độ rất lớn đối với tôi nhưng tôi tò mò liệu câu trả lời được chấp nhận là nhanh hơn hay chậm hơn thì sao?
Dan

Cách tiếp cận này thực sự tốt khi sửa đổi nhiều bảng trong một giao dịch, điều mà tôi thấy mình thường làm khi tải hàng loạt cơ sở dữ liệu.
Frank

Hãy lưu ý rằng phương pháp này sẽ không hoạt động nếu bạn cần sử dụng các ràng buộc . Công cụ SQLite3 sẽ cho rằng tất cả các ràng buộc của bạn sẽ được áp dụng trên câu lệnh đầu tiên và bỏ qua các câu lệnh sau. Xem câu hỏi SO này để được giải thích chi tiết hơn.
Philippe Hebert

38

Theo trang này, nó không được hỗ trợ:

  • 2007-12-03: Không hỗ trợ INSERT nhiều hàng hay còn gọi là hợp chất INSERT.
  INSERT INTO table (col1, col2) VALUES 
      ('row1col1', 'row1col2'), ('row2col1', 'row2col2'), ...

Trên thực tế, theo tiêu chuẩn SQL92, một biểu thức GIÁ TRỊ sẽ có thể tự đứng vững. Ví dụ: sau đây sẽ trả về một bảng một cột có ba hàng:VALUES 'john', 'mary', 'paul';

Kể từ phiên bản 3.7.11 SQLite không hỗ trợ chèn nhiều hàng . Richard Hipp bình luận:

"Chèn đa giá trị mới chỉ là đường dẫn cú pháp (sic) cho chèn ghép. Không có lợi thế về hiệu suất theo cách này hay cách khác."


Không có lợi thế về hiệu suất theo cách này hay cách khác. - Bạn có thể cho tôi biết bạn đã nhìn thấy nhận xét đó ở đâu? Tôi không thể tìm thấy nó ở bất cứ đâu.
Alix Axel

15

Bắt đầu từ phiên bản 2012-03-20 (3.7.11), sqlite hỗ trợ cú pháp INSERT sau:

INSERT INTO 'tablename' ('column1', 'column2') VALUES
  ('data1', 'data2'),
  ('data3', 'data4'),
  ('data5', 'data6'),
  ('data7', 'data8');

Đọc tài liệu: http://www.sqlite.org/lang_insert.html

PS: Vui lòng +1 để trả lời / trả lời của Brian Campbell. không phải của tôi! Ông trình bày giải pháp trước.


10

Như các áp phích khác đã nói, SQLite không hỗ trợ cú pháp này. Tôi không biết liệu INSERT hỗn hợp có phải là một phần của tiêu chuẩn SQL hay không, nhưng theo kinh nghiệm của tôi, chúng không được triển khai trong nhiều sản phẩm.

Bên cạnh đó, bạn nên lưu ý rằng hiệu suất INSERT trong SQLite được cải thiện đáng kể nếu bạn bọc nhiều INSERT trong một giao dịch rõ ràng.


10

Vâng, sql có thể làm điều này, nhưng với một cú pháp khác. Nhân tiện, tài liệu sqlite là khá tốt. Nó cũng sẽ cho bạn biết rằng cách duy nhất để chèn một số hàng là sử dụng câu lệnh select làm nguồn dữ liệu được chèn.


9

Sqlite3 không thể thực hiện điều đó trực tiếp trong SQL ngoại trừ thông qua CHỌN và trong khi CHỌN có thể trả về một "hàng" biểu thức, tôi biết không có cách nào để làm cho nó trả về một cột giả mạo.

Tuy nhiên, CLI có thể làm điều đó:

.import FILE TABLE     Import data from FILE into TABLE
.separator STRING      Change separator used by output mode and .import

$ sqlite3 /tmp/test.db
SQLite version 3.5.9
Enter ".help" for instructions
sqlite> create table abc (a);
sqlite> .import /dev/tty abc
1
2
3
99
^D
sqlite> select * from abc;
1
2
3
99
sqlite> 

Nếu bạn đặt một vòng lặp xung quanh một INSERT, thay vì sử dụng .importlệnh CLI , thì hãy chắc chắn làm theo lời khuyên trong Câu hỏi thường gặp về sqlite về tốc độ INSERT:

Theo mặc định, mỗi câu lệnh INSERT là giao dịch riêng của nó. Nhưng nếu bạn bao quanh nhiều câu lệnh INSERT bằng BEGIN ... CAM KẾT thì tất cả các phần chèn được nhóm thành một giao dịch. Thời gian cần thiết để thực hiện giao dịch được khấu hao trên tất cả các câu lệnh chèn kèm theo và do đó thời gian cho mỗi câu lệnh chèn được giảm đáng kể.

Một tùy chọn khác là chạy PRAGMA đồng bộ = TẮT. Lệnh này sẽ khiến SQLite không chờ dữ liệu đến bề mặt đĩa, điều này sẽ khiến các thao tác ghi dường như nhanh hơn nhiều. Nhưng nếu bạn mất điện giữa giao dịch, tệp cơ sở dữ liệu của bạn có thể bị hỏng.


Nếu bạn xem mã nguồn cho .importlệnh của SQLite , thì đó chỉ là một vòng lặp, đọc một dòng từ tệp đầu vào (hoặc tty) và sau đó là một câu lệnh INSERT cho dòng đó. Thật không may, hiệu quả không được cải thiện đáng kể.
Bill Karwin

8

Alex là chính xác: tuyên bố "chọn ... liên minh" sẽ mất thứ tự rất quan trọng đối với một số người dùng. Ngay cả khi bạn chèn theo một thứ tự cụ thể, sqlite thay đổi mọi thứ vì vậy thích sử dụng các giao dịch nếu thứ tự chèn là quan trọng.

create table t_example (qid int not null, primary key (qid));
begin transaction;
insert into "t_example" (qid) values (8);
insert into "t_example" (qid) values (4);
insert into "t_example" (qid) values (9);
end transaction;    

select rowid,* from t_example;
1|8
2|4
3|9

8

sợ hãi_fool có một câu trả lời tuyệt vời cho các phiên bản cũ hơn. Tôi chỉ muốn thêm rằng bạn cần đảm bảo rằng bạn có tất cả các cột được liệt kê. Vì vậy, nếu bạn có 3 cột, bạn cần đảm bảo chọn hành động trên 3 cột.

Ví dụ: Tôi có 3 cột nhưng tôi chỉ muốn chèn 2 cột giá trị dữ liệu. Giả sử tôi không quan tâm đến cột đầu tiên vì đó là id số nguyên tiêu chuẩn. Tôi có thể làm như sau ...

INSERT INTO 'tablename'
      SELECT NULL AS 'column1', 'data1' AS 'column2', 'data2' AS 'column3'
UNION SELECT NULL, 'data3', 'data4'
UNION SELECT NULL, 'data5', 'data6'
UNION SELECT NULL, 'data7', 'data8'

Lưu ý: Hãy nhớ câu lệnh "select ... union" sẽ mất thứ tự. (Từ AG1)


7
INSERT INTO TABLE_NAME 
            (DATA1, 
             DATA2) 
VALUES      (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2), 
            (VAL1, 
             VAL2); 

6

Bạn không thể nhưng tôi không nghĩ rằng bạn bỏ lỡ bất cứ điều gì.

Bởi vì bạn gọi sqlite luôn trong quá trình, nên hầu như không có vấn đề gì về hiệu suất cho dù bạn thực hiện 1 câu lệnh chèn hay 100 câu lệnh chèn. Tuy nhiên, cam kết mất rất nhiều thời gian vì vậy hãy đặt 100 lần chèn đó vào trong một giao dịch.

Sqlite nhanh hơn nhiều khi bạn sử dụng các truy vấn được tham số hóa (cần ít phân tích cú pháp hơn) vì vậy tôi sẽ không nối các câu lệnh lớn như thế này:

insert into mytable (col1, col2)
select 'a','b'
union 
select 'c','d'
union ...

Chúng cần được phân tích cú pháp nhiều lần vì mỗi câu lệnh được nối là khác nhau.


6

trong mysql, bạn không thể chèn nhiều giá trị, nhưng bạn có thể tiết kiệm thời gian bằng cách mở kết nối chỉ một lần và sau đó thực hiện tất cả các thao tác chèn rồi đóng kết nối. Nó tiết kiệm rất nhiều thời gian


5

Vấn đề với việc sử dụng giao dịch là bạn cũng khóa bảng để đọc. Vì vậy, nếu bạn thực sự có nhiều dữ liệu để chèn và bạn cần truy cập vào dữ liệu của mình, ví dụ như một bản xem trước hoặc như vậy, cách này không hoạt động tốt.

Vấn đề với giải pháp khác là bạn mất thứ tự chèn

insert into mytable (col)
select 'c'
union 
select 'd'
union 
select 'a'
union 
select 'b';

Trong sqlite, dữ liệu sẽ được lưu trữ a, b, c, d ...


5

Kể từ phiên bản 3.7.11 SQLite không hỗ trợ chèn nhiều hàng. Richard Hipp bình luận:

Tôi đang sử dụng 3.6.13

Tôi ra lệnh như thế này:

insert into xtable(f1,f2,f3) select v1 as f1, v2 as f2, v3 as f3 
union select nextV1+, nextV2+, nextV3+

Với 50 bản ghi được chèn tại một thời điểm, chỉ mất một giây hoặc ít hơn.

Thật sự sử dụng sqlite để chèn nhiều hàng cùng một lúc là rất có thể. Bởi @Andy đã viết.

cảm ơn Andy +1


4
INSERT INTO tabela(coluna1,coluna2) 
SELECT 'texto','outro'
UNION ALL 
SELECT 'mais texto','novo texto';

2

Nếu bạn sử dụng plugin firefox của trình quản lý Sqlite , nó hỗ trợ chèn hàng loạt từ INSERTcác câu lệnh SQL.

Thực ra nó không hỗ trợ điều này, nhưng Sqlite Browser thì có (hoạt động trên Windows, OS X, Linux)


2

Tôi có một truy vấn như bên dưới, nhưng với trình điều khiển ODBC, SQLite có lỗi với "," nó nói. Tôi chạy vbscript trong HTA (Ứng dụng Html).

INSERT INTO evrak_ilac_iliskileri (evrak_id, ilac_id, baglayan_kullanici_id, tarih) VALUES (4150,762,1,datetime()),(4150,9770,1,datetime()),(4150,6609,1,datetime()),(4150,3628,1,datetime()),(4150,9422,1,datetime())

2

Trên sqlite 3.7.2:

INSERT INTO table_name (column1, column2) 
                SELECT 'value1', 'value1' 
          UNION SELECT 'value2', 'value2' 
          UNION SELECT 'value3', 'value3' 

và như thế


2

Tôi có thể làm cho truy vấn động. Đây là bảng của tôi:

CREATE TABLE "tblPlanner" ("probid" text,"userid" TEXT,"selectedtime" DATETIME,"plannerid" TEXT,"isLocal" BOOL,"applicationid" TEXT, "comment" TEXT, "subject" TEXT)

và tôi nhận được tất cả dữ liệu thông qua a JSON, vì vậy sau khi nhận được mọi thứ bên trong, NSArraytôi đã làm theo điều này:

    NSMutableString *query = [[NSMutableString alloc]init];
    for (int i = 0; i < arr.count; i++)
    {
        NSString *sqlQuery = nil;
        sqlQuery = [NSString stringWithFormat:@" ('%@', '%@', '%@', '%@', '%@', '%@', '%@', '%@'),",
                    [[arr objectAtIndex:i] objectForKey:@"plannerid"],
                    [[arr objectAtIndex:i] objectForKey:@"probid"],
                    [[arr objectAtIndex:i] objectForKey:@"userid"],
                    [[arr objectAtIndex:i] objectForKey:@"selectedtime"],
                    [[arr objectAtIndex:i] objectForKey:@"isLocal"],
                    [[arr objectAtIndex:i] objectForKey:@"subject"],
                    [[arr objectAtIndex:i] objectForKey:@"comment"],
                    [[NSUserDefaults standardUserDefaults] objectForKey:@"applicationid"]
                    ];
        [query appendString:sqlQuery];
    }
    // REMOVING LAST COMMA NOW
    [query deleteCharactersInRange:NSMakeRange([query length]-1, 1)];

    query = [NSString stringWithFormat:@"insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values%@",query];

Và cuối cùng là truy vấn đầu ra là:

insert into tblPlanner (plannerid, probid, userid, selectedtime, isLocal, applicationid, subject, comment) values 
<append 1>
('pl1176428260', '', 'US32552', '2013-06-08 12:00:44 +0000', '0', 'subj', 'Hiss', 'ap19788'),
<append 2>
('pl2050411638', '', 'US32552', '2013-05-20 10:45:55 +0000', '0', 'TERI', 'Yahoooooooooo', 'ap19788'), 
<append 3>
('pl1828600651', '', 'US32552', '2013-05-21 11:33:33 +0000', '0', 'test', 'Yest', 'ap19788'),
<append 4>
('pl549085534', '', 'US32552', '2013-05-19 11:45:04 +0000', '0', 'subj', 'Comment', 'ap19788'), 
<append 5>
('pl665538927', '', 'US32552', '2013-05-29 11:45:41 +0000', '0', 'subj', '1234567890', 'ap19788'), 
<append 6>
('pl1969438050', '', 'US32552', '2013-06-01 12:00:18 +0000', '0', 'subj', 'Cmt', 'ap19788'),
<append 7>
('pl672204050', '', 'US55240280', '2013-05-23 12:15:58 +0000', '0', 'aassdd', 'Cmt', 'ap19788'), 
<append 8>
('pl1019026150', '', 'US32552', '2013-06-08 12:15:54 +0000', '0', 'exists', 'Cmt', 'ap19788'), 
<append 9>
('pl790670523', '', 'US55240280', '2013-05-26 12:30:21 +0000', '0', 'qwerty', 'Cmt', 'ap19788')

cũng đang chạy tốt thông qua mã và tôi có thể lưu mọi thứ trong SQLite thành công.

Trước đó, tôi đã tạo UNIONcông cụ truy vấn động nhưng bắt đầu đưa ra một số lỗi cú pháp. Dù sao, điều này đang chạy tốt cho tôi.


2

Tôi ngạc nhiên rằng không ai đã đề cập đến các tuyên bố chuẩn bị . Trừ khi bạn tự mình sử dụng SQL và không sử dụng bất kỳ ngôn ngữ nào khác, thì tôi sẽ nghĩ rằng các câu lệnh được chuẩn bị trong một giao dịch sẽ là cách hiệu quả nhất để chèn nhiều hàng.


1
Các tuyên bố đã chuẩn bị luôn là một ý tưởng tốt, nhưng hoàn toàn không liên quan đến câu hỏi mà OP đang hỏi. Anh ta đang hỏi cú pháp cơ bản để chèn nhiều dữ liệu trong một câu lệnh là gì.
Lakey

0

bạn có thể sử dụng insertHelper, nó rất dễ dàng và nhanh chóng

tài liệu: http://developer.android.com/reference/android/database/DatabaseUtils.InsertHelper.html

hướng dẫn: http://www.outofwhatbox.com/blog/2010/12/android-USE-databaseutils-inserthelper-for-faster-insertions-into-sqlite-database/

Chỉnh sửa: ChènHelper không được chấp nhận kể từ API Cấp 17


3
ChènHelper đã không được chấp nhận kể từ API 17
GregM

-1

Nếu bạn đang sử dụng bash shell, bạn có thể sử dụng:

time bash -c $'
FILE=/dev/shm/test.db
sqlite3 $FILE "create table if not exists tab(id int);"
sqlite3 $FILE "insert into tab values (1),(2)"
for i in 1 2 3 4; do sqlite3 $FILE "INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5"; done; 
sqlite3 $FILE "select count(*) from tab;"'

Hoặc nếu bạn đang ở trong sqlite CLI, thì bạn cần phải làm điều này:

create table if not exists tab(id int);"
insert into tab values (1),(2);
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5;
select count(*) from tab;

Làm thế nào nó hoạt động? Nó sử dụng điều đó nếu bảng tab:

id int
------
1
2

sau đó select a.id, b.id from tab a, tab btrở về

a.id int | b.id int
------------------
    1    | 1
    2    | 1
    1    | 2
    2    | 2

và như thế. Sau khi thực hiện đầu tiên, chúng tôi chèn 2 hàng, sau đó 2 ^ 3 = 8. (ba vì chúng ta có tab a, tab b, tab c)

Sau khi thực hiện lần thứ hai, chúng tôi chèn các (2+8)^3=1000hàng bổ sung

Sau đó, chúng tôi chèn khoảng max(1000^3, 5e5)=500000hàng và cứ thế ...

Đây là phương pháp nhanh nhất được biết đến với tôi về cơ sở dữ liệu SQLite.


2
Điều này không hoạt động nếu bạn muốn chèn dữ liệu hữu ích .
CL.

@CL. nó không đúng. bạn có thể kết hợp nó với ngày và id ngẫu nhiên theo cách bạn muốn.
test30
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.